diff --git a/src/ptvsd/_vendored/pydevd/_pydevd_bundle/pydevd_comm.py b/src/ptvsd/_vendored/pydevd/_pydevd_bundle/pydevd_comm.py index d66db8a2..a3d77af1 100644 --- a/src/ptvsd/_vendored/pydevd/_pydevd_bundle/pydevd_comm.py +++ b/src/ptvsd/_vendored/pydevd/_pydevd_bundle/pydevd_comm.py @@ -897,8 +897,10 @@ def internal_evaluate_expression_json(py_db, request, thread_id): elif context == 'repl': try: pydevd_vars.evaluate_expression(py_db, frame, expression, is_exec=True) - except: - pass + except Exception as ex: + err = ''.join(traceback.format_exception_only(type(ex), ex)) + _evaluate_response(py_db, request, result='', error_message=err) + return # No result on exec. _evaluate_response(py_db, request, result='') return diff --git a/src/ptvsd/_vendored/pydevd/tests_python/resources/_debugger_case_evaluate.py b/src/ptvsd/_vendored/pydevd/tests_python/resources/_debugger_case_evaluate.py new file mode 100644 index 00000000..ba014799 --- /dev/null +++ b/src/ptvsd/_vendored/pydevd/tests_python/resources/_debugger_case_evaluate.py @@ -0,0 +1,8 @@ +def Call(): + var_1 = 5 + + var_all = 1 # Break here + +if __name__ == '__main__': + Call() + print('TEST SUCEEDED!') \ No newline at end of file diff --git a/src/ptvsd/_vendored/pydevd/tests_python/test_debugger_json.py b/src/ptvsd/_vendored/pydevd/tests_python/test_debugger_json.py index 14f43acf..f23d821b 100644 --- a/src/ptvsd/_vendored/pydevd/tests_python/test_debugger_json.py +++ b/src/ptvsd/_vendored/pydevd/tests_python/test_debugger_json.py @@ -939,6 +939,49 @@ def test_stepping(case_setup): writer.finished_ok = True +def test_evaluate(case_setup): + with case_setup.test_file('_debugger_case_evaluate.py') as writer: + json_facade = JsonFacade(writer) + + writer.write_set_protocol('http_json') + writer.write_add_breakpoint(writer.get_line_index_with_content('Break here')) + + json_facade.write_make_initial_run() + + hit = writer.wait_for_breakpoint_hit() + + stack_trace_request = json_facade.write_request( + pydevd_schema.StackTraceRequest(pydevd_schema.StackTraceArguments(threadId=hit.thread_id))) + stack_trace_response = json_facade.wait_for_response(stack_trace_request) + stack_frame = next(iter(stack_trace_response.body.stackFrames)) + stack_frame_id = stack_frame['id'] + + # Test evaluate request that results in 'eval' + eval_request = json_facade.write_request( + pydevd_schema.EvaluateRequest(pydevd_schema.EvaluateArguments('var_1', frameId=stack_frame_id, context='repl'))) + eval_response = json_facade.wait_for_response(eval_request) + assert eval_response.body.result == '5' + assert eval_response.body.type == 'int' + + # Test evaluate request that results in 'exec' + exec_request = json_facade.write_request( + pydevd_schema.EvaluateRequest(pydevd_schema.EvaluateArguments('var_1 = 6', frameId=stack_frame_id, context='repl'))) + exec_response = json_facade.wait_for_response(exec_request) + assert exec_response.body.result == '' + + # Test evaluate request that results in 'exec' but fails + exec_request = json_facade.write_request( + pydevd_schema.EvaluateRequest(pydevd_schema.EvaluateArguments('var_1 = "abc"/6', frameId=stack_frame_id, context='repl'))) + exec_response = json_facade.wait_for_response(exec_request) + assert exec_response.success == False + assert exec_response.body.result == '' + assert exec_response.message.find('TypeError') > -1 + + writer.write_run_thread(hit.thread_id) + + writer.finished_ok = True + + @pytest.mark.skipif(IS_JYTHON, reason='Flaky on Jython.') def test_path_translation_and_source_reference(case_setup): diff --git a/src/ptvsd/wrapper.py b/src/ptvsd/wrapper.py index 7735528c..7d077a35 100644 --- a/src/ptvsd/wrapper.py +++ b/src/ptvsd/wrapper.py @@ -1656,6 +1656,11 @@ class VSCodeMessageProcessor(VSCLifecycleMsgProcessor): is_json=True) body = resp_args['body'] + + # Currently there is an issue in VSC where returning success=false for a eval request, + # in repl context. VSC does not show the error response in the debug console. + if args.get('context', None) == 'repl' and not resp_args['success']: + body['result'] = resp_args['message'] self.send_response(request, **body) @async_handler