From f99a1769f5016239eb80dfbd6e2b90a0a8cb2b1b Mon Sep 17 00:00:00 2001 From: Alexander Koshevoy Date: Mon, 20 Jul 2020 15:04:42 +0300 Subject: [PATCH] PY-42932 Fix extensive error logging on the attempts to connect to Python debugger during the process is started GitOrigin-RevId: a6611c306524ec62ddc179bff7e1614dcd028f7b --- .../debugger/pydev/AbstractCommand.java | 13 +-- .../python/debugger/pydev/RemoteDebugger.java | 99 ++++++++++--------- 2 files changed, 58 insertions(+), 54 deletions(-) diff --git a/python/pydevSrc/com/jetbrains/python/debugger/pydev/AbstractCommand.java b/python/pydevSrc/com/jetbrains/python/debugger/pydev/AbstractCommand.java index 73580b031186..7434a4c5c96f 100644 --- a/python/pydevSrc/com/jetbrains/python/debugger/pydev/AbstractCommand.java +++ b/python/pydevSrc/com/jetbrains/python/debugger/pydev/AbstractCommand.java @@ -1,12 +1,9 @@ package com.jetbrains.python.debugger.pydev; import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.diagnostic.Logger; import com.jetbrains.python.debugger.PyDebuggerException; import org.jetbrains.annotations.NotNull; -import java.lang.invoke.MethodHandles; - public abstract class AbstractCommand { @@ -87,7 +84,6 @@ public abstract class AbstractCommand { private final ResponseProcessor myResponseProcessor; - public static final Logger LOG = Logger.getInstance(MethodHandles.lookup().lookupClass()); protected AbstractCommand(@NotNull final RemoteDebugger debugger, final int commandCode) { myDebugger = debugger; @@ -146,18 +142,15 @@ public abstract class AbstractCommand { if (processor == null && !isResponseExpected()) return; if (!frameSent) { - LOG.error("Couldn't send frame " + myCommandCode); - return; + throw new PyDebuggerException("Couldn't send frame " + myCommandCode); } frame = myDebugger.waitForResponse(sequence, getResponseTimeout()); if (frame == null) { - String errorMessage = "Timeout waiting for response on " + myCommandCode; if (!myDebugger.isConnected()) { - errorMessage = "No connection (command: " + myCommandCode + " )"; + throw new PyDebuggerException("No connection (command: " + myCommandCode + " )"); } - LOG.error(errorMessage); - return; + throw new PyDebuggerException("Timeout waiting for response on " + myCommandCode); } if (processor != null) { processor.processResponse(frame); diff --git a/python/pydevSrc/com/jetbrains/python/debugger/pydev/RemoteDebugger.java b/python/pydevSrc/com/jetbrains/python/debugger/pydev/RemoteDebugger.java index 59ecb38baac4..569aa427330a 100644 --- a/python/pydevSrc/com/jetbrains/python/debugger/pydev/RemoteDebugger.java +++ b/python/pydevSrc/com/jetbrains/python/debugger/pydev/RemoteDebugger.java @@ -154,9 +154,7 @@ public class RemoteDebugger implements ProcessDebugger { final boolean execute, boolean trimResult) throws PyDebuggerException { - final EvaluateCommand command = new EvaluateCommand(this, threadId, frameId, expression, execute, trimResult); - command.execute(); - return command.getValue(); + return executeCommand(new EvaluateCommand(this, threadId, frameId, expression, execute, trimResult)).getValue(); } @Override @@ -167,26 +165,21 @@ public class RemoteDebugger implements ProcessDebugger { @Override public XValueChildrenList loadFrame(final String threadId, final String frameId) throws PyDebuggerException { - final GetFrameCommand command = new GetFrameCommand(this, threadId, frameId); - command.execute(); - return command.getVariables(); + return executeCommand(new GetFrameCommand(this, threadId, frameId)).getVariables(); } @Override public List> getSmartStepIntoVariants(String threadId, String frameId, int startContextLine, int endContextLine) throws PyDebuggerException { - GetSmartStepIntoVariantsCommand command = new GetSmartStepIntoVariantsCommand(this, threadId, frameId, startContextLine, endContextLine); - command.execute(); - return command.getVariants(); + return executeCommand(new GetSmartStepIntoVariantsCommand(this, threadId, frameId, startContextLine, endContextLine)) + .getVariants(); } // todo: don't generate temp variables for qualified expressions - just split 'em @Override public XValueChildrenList loadVariable(final String threadId, final String frameId, final PyDebugValue var) throws PyDebuggerException { setTempVariable(threadId, frameId, var); - final GetVariableCommand command = new GetVariableCommand(this, threadId, frameId, var); - command.execute(); - return command.getVariables(); + return executeCommand(new GetVariableCommand(this, threadId, frameId, var)).getVariables(); } @Override @@ -198,9 +191,7 @@ public class RemoteDebugger implements ProcessDebugger { int rows, int cols, String format) throws PyDebuggerException { - final GetArrayCommand command = new GetArrayCommand(this, threadId, frameId, var, rowOffset, colOffset, rows, cols, format); - command.execute(); - return command.getArray(); + return executeCommand(new GetArrayCommand(this, threadId, frameId, var, rowOffset, colOffset, rows, cols, format)).getArray(); } @Override @@ -217,7 +208,7 @@ public class RemoteDebugger implements ProcessDebugger { final String frameId, final PyReferringObjectsValue var, final PyDebugCallback callback) { - RunCustomOperationCommand cmd = new GetReferrersCommand(this, threadId, frameId, var); + GetReferrersCommand cmd = new GetReferrersCommand(this, threadId, frameId, var); cmd.execute(new PyDebugCallback>() { @Override @@ -245,26 +236,21 @@ public class RemoteDebugger implements ProcessDebugger { private PyDebugValue doChangeVariable(final String threadId, final String frameId, final String varName, final String value) throws PyDebuggerException { - final ChangeVariableCommand command = new ChangeVariableCommand(this, threadId, frameId, varName, value); - command.execute(); - return command.getNewValue(); + return executeCommand(new ChangeVariableCommand(this, threadId, frameId, varName, value)).getNewValue(); } @Override public void loadFullVariableValues(@NotNull String threadId, @NotNull String frameId, @NotNull List> vars) throws PyDebuggerException { - final LoadFullValueCommand command = new LoadFullValueCommand(this, threadId, frameId, vars); - command.execute(); + executeCommand(new LoadFullValueCommand(this, threadId, frameId, vars)); } @Override @Nullable public String loadSource(String path) { - LoadSourceCommand command = new LoadSourceCommand(this, path); try { - command.execute(); - return command.getContent(); + return executeCommand(new LoadSourceCommand(this, path)).getContent(); } catch (PyDebuggerException e) { return "#Couldn't load source of file " + path; @@ -458,7 +444,7 @@ public class RemoteDebugger implements ProcessDebugger { @Override public void run() throws PyDebuggerException { - new RunCommand(this).execute(); + executeCommand(new RunCommand(this)); } @Override @@ -479,29 +465,12 @@ public class RemoteDebugger implements ProcessDebugger { @NotNull XSourcePosition sourcePosition, @Nullable String functionName, @NotNull PyDebugCallback> callback) { - final SetNextStatementCommand command = new SetNextStatementCommand(this, threadId, sourcePosition, functionName, callback); - try { - command.execute(); - } - catch (PyDebuggerException e) { - if (isConnected()) { - LOG.error(e); - } - } + executeCommandSafely(new SetNextStatementCommand(this, threadId, sourcePosition, functionName, callback)); } @Override public void setTempBreakpoint(@NotNull String type, @NotNull String file, int line) { - final SetBreakpointCommand command = - new SetBreakpointCommand(this, type, file, line); - try { - command.execute(); - } - catch (PyDebuggerException e) { - if (isConnected()) { - LOG.error(e); - } - } + executeCommandSafely(new SetBreakpointCommand(this, type, file, line)); myTempBreakpoints.put(Pair.create(file, line), type); } @@ -791,4 +760,46 @@ public class RemoteDebugger implements ProcessDebugger { listener.detached(); } } + + /** + * Executes the command and returns it. + *

+ * If the command execution throws an exception and the debugger is in + * "connected" state then the exception is rethrown. If the debugger is not + * connected at this moment then the exception is ignored. + * + * @param command + */ + private > T executeCommand(@NotNull T command) throws PyDebuggerException { + try { + command.execute(); + } + catch (PyDebuggerException e) { + if (isConnected()) { + throw e; + } + } + return command; + } + + /** + * Executes the command safely. In case of {@link PyDebuggerException}, the + * exception is only logged. + *

+ * If the command execution throws an exception and the debugger is in + * "connected" state then the error is logged. If the debugger is not + * connected at this moment then the exception is ignored. + * + * @param command + */ + private > void executeCommandSafely(@NotNull T command) { + try { + command.execute(); + } + catch (PyDebuggerException e) { + if (isConnected()) { + LOG.error(command); + } + } + } }