Repository: microsoft/ptvsd

Issue:
on_source special cases should be ported to pydevd and it should use _forward_request_to_pydevd
Note: `_forward_request_to_pydevd` should `send_error_response` when needed.


Discussion:

Resolving patch:
diff --git a/src/ptvsd/_vendored/pydevd/_pydevd_bundle/pydevd_process_net_command_json.py b/src/ptvsd/_vendored/pydevd/_pydevd_bundle/pydevd_process_net_command_json.py
--- a/src/ptvsd/_vendored/pydevd/_pydevd_bundle/pydevd_process_net_command_json.py
+++ b/src/ptvsd/_vendored/pydevd/_pydevd_bundle/pydevd_process_net_command_json.py
@@ -702,7 +702,9 @@ def on_source_request(self, py_db, request):
         response_args = {'body': body}
 
         if content is None:
-            if server_filename:
+            if source_reference == 0:
+                message = 'Source unavailable'
+            elif server_filename:
                 message = 'Unable to retrieve source for %s' % (server_filename,)
             else:
                 message = 'Invalid sourceReference %d' % (source_reference,)
diff --git a/src/ptvsd/wrapper.py b/src/ptvsd/wrapper.py
--- a/src/ptvsd/wrapper.py
+++ b/src/ptvsd/wrapper.py
@@ -1421,25 +1421,8 @@ def on_threads(self, request, args):
 
         self.send_response(request, threads=threads)
 
-    @async_handler
     def on_source(self, request, args):
-        """Request to get the source"""
-        source_reference = args.get('sourceReference', 0)
-
-        if source_reference == 0:
-            self.send_error_response(request, 'Source unavailable')
-        else:
-            pydevd_request = copy.deepcopy(request)
-            del pydevd_request['seq']  # A new seq should be created for pydevd.
-            _, _, resp_args = yield self.pydevd_request(
-                pydevd_comm.CMD_LOAD_SOURCE,
-                pydevd_request,
-                is_json=True)
-
-            if resp_args.get('success', True):
-                self.send_response(request, **resp_args['body'])
-            else:
-                self.send_error_response(request, resp_args.get('message', 'Error retrieving source'))
+        self._forward_request_to_pydevd(request, args)
 
     def on_stackTrace(self, request, args):
         self._forward_request_to_pydevd(request, args)


Test patch:
diff --git a/tests/func/test_path_mapping.py b/tests/func/test_path_mapping.py
--- a/tests/func/test_path_mapping.py
+++ b/tests/func/test_path_mapping.py
@@ -5,6 +5,7 @@
 from __future__ import print_function, with_statement, absolute_import
 
 import os
+import traceback
 from shutil import copyfile
 from tests.helpers.pattern import Path
 from tests.helpers.session import DebugSession
@@ -162,10 +163,17 @@ def call_func():
         source_reference = frames[1]['source']['sourceReference']
         assert source_reference > 0  # Unmapped file should have a source reference.
 
-        resp_variables = session.send_request('source', arguments={
+        resp_source = session.send_request('source', arguments={
+            'sourceReference': 0
+        }).wait_for_response(raise_if_failed=False)
+        assert not resp_source.success
+        text = ''.join(traceback.format_exception_only(type(resp_source.body), resp_source.body))
+        assert 'Source unavailable' in text
+
+        resp_source = session.send_request('source', arguments={
             'sourceReference': source_reference
         }).wait_for_response()
-        assert "def call_me_back(callback):" in (resp_variables.body['content'])
+        assert "def call_me_back(callback):" in (resp_source.body['content'])
 
         remote_code_path = session.read_json()
         assert path_remote == Path(remote_code_path)