diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessEvents.java b/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessEvents.java index ce9292b010cf..9b94571431dc 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessEvents.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessEvents.java @@ -49,7 +49,12 @@ import com.intellij.util.ConcurrencyUtil; import com.intellij.util.TimeoutUtil; import com.intellij.util.concurrency.AppExecutorUtil; import com.intellij.util.containers.ContainerUtil; +import com.intellij.xdebugger.DapMode; +import com.intellij.xdebugger.BreakpointErrorData; +import com.intellij.xdebugger.XBreakpointBehaviorPolicy.BreakpointErrorAction; import com.intellij.xdebugger.XDebugSession; +import com.intellij.xdebugger.XBreakpointBehaviorPolicy; +import com.intellij.xdebugger.XDebuggerManager; import com.intellij.xdebugger.breakpoints.XBreakpoint; import com.intellij.xdebugger.impl.XDebugSessionImpl; import com.intellij.xdebugger.impl.XDebuggerManagerImpl; @@ -766,13 +771,30 @@ public class DebugProcessEvents extends DebugProcessImpl { catch (final LocatableEventRequestor.EventProcessingException ex) { // stop timer here to prevent reporting dialog opened time endTimeNs = System.nanoTime(); - String exceptionMessage = ex.getMessage(); + String exceptionMessage = Objects.toString(ex.getMessage(), ""); if (LOG.isDebugEnabled()) { LOG.debug(exceptionMessage); } String title = ex.getTitle(); + XBreakpoint> xBreakpoint = requestor instanceof Breakpoint> breakpoint ? breakpoint.getXBreakpoint() : null; + XDebugSession xDebugSession = getSession().getXDebugSession(); + BreakpointErrorData errorData = new BreakpointErrorData(title, exceptionMessage, ex.getCause()); + BreakpointErrorAction policyAction = (xDebugSession == null || xBreakpoint == null) + ? BreakpointErrorAction.UNHANDLED + : XBreakpointBehaviorPolicy.doChooseBreakpointErrorAction(xDebugSession, xBreakpoint, errorData); + final String displayName = DebuggerUtilsImpl.getRequestorStringForUser(requestor); - requestHit = DebuggerUtilsImpl.askAboutPauseOnException(getProject(), displayName, exceptionMessage, title); + if (policyAction != BreakpointErrorAction.UNHANDLED) { + requestHit = policyAction == BreakpointErrorAction.PAUSE; + } + else { + requestHit = DebuggerUtilsImpl.askAboutPauseOnException(getProject(), displayName, exceptionMessage, title); + } + + if (xDebugSession != null && xBreakpoint != null) { + XDebuggerManagerImpl debuggerManager = (XDebuggerManagerImpl)XDebuggerManager.getInstance(xDebugSession.getProject()); + debuggerManager.getBreakpointManager().fireBreakpointError(xBreakpoint, xDebugSession, errorData); + } resumePreferred = !requestHit; } catch (VMDisconnectedException e) { diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/Breakpoint.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/Breakpoint.java index adee31cfbbfe..8396566571eb 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/Breakpoint.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/Breakpoint.java @@ -67,11 +67,17 @@ import com.intellij.util.ThreeState; import com.intellij.util.concurrency.AppExecutorUtil; import com.intellij.util.containers.ContainerUtil; import com.intellij.xdebugger.XExpression; +import com.intellij.xdebugger.BreakpointErrorData; +import com.intellij.xdebugger.DapMode; +import com.intellij.xdebugger.XDebugSession; +import com.intellij.xdebugger.XDebuggerManager; +import com.intellij.xdebugger.XExpression; import com.intellij.xdebugger.breakpoints.SuspendPolicy; import com.intellij.xdebugger.breakpoints.XBreakpoint; import com.intellij.xdebugger.breakpoints.XLineBreakpoint; import com.intellij.xdebugger.impl.XDebugSessionImpl; import com.intellij.xdebugger.impl.XDebuggerHistoryManager; +import com.intellij.xdebugger.impl.XDebuggerManagerImpl; import com.intellij.xdebugger.impl.ui.DebuggerUIUtil; import com.intellij.xdebugger.impl.breakpoints.XBreakpointBase; import com.intellij.xdebugger.impl.breakpoints.XBreakpointUtil; @@ -414,9 +420,20 @@ public abstract class Breakpoint
implements
}
catch (EvaluateException e) {
JavaDebuggerEvaluatorStatisticsCollector.logEvaluationResult(myProject, evaluator, false, XEvaluationOrigin.BREAKPOINT_LOG);
- buf.append(JavaDebuggerBundle.message("error.unable.to.evaluate.expression"))
- .append(" \"").append(logMessage).append("\"")
- .append(" : ").append(e.getMessage());
+ String errorMessage = JavaDebuggerBundle.message("error.unable.to.evaluate.expression") +
+ " \"" + logMessage + "\"" +
+ " : " + e.getMessage();
+ buf.append(errorMessage);
+
+ XDebugSession session = debugProcess.getSession().getXDebugSession();
+ if (session != null) {
+ XDebuggerManagerImpl debuggerManager = (XDebuggerManagerImpl)XDebuggerManager.getInstance(myProject);
+ debuggerManager.getBreakpointManager().fireBreakpointError(getXBreakpoint(),
+ session,
+ new BreakpointErrorData(JavaDebuggerBundle.message("title.error.evaluating.breakpoint.action"),
+ errorMessage,
+ e));
+ }
}
buf.append("\n");
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointManager.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointManager.java
index 396915c1020b..da1745b713fe 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointManager.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointManager.java
@@ -47,6 +47,7 @@ import com.intellij.util.concurrency.AppExecutorUtil;
import com.intellij.util.concurrency.ThreadingAssertions;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.messages.MessageBusConnection;
+import com.intellij.xdebugger.XDebugSession;
import com.intellij.xdebugger.XDebuggerManager;
import com.intellij.xdebugger.XDebuggerUtil;
import com.intellij.xdebugger.XSourcePosition;
@@ -694,5 +695,10 @@ public class BreakpointManager {
void multicastLogMessage(Breakpoint> breakpoint, String message, DebugProcessImpl debugProcess) {
myLogMessageDispatcher.getMulticaster().onLogMessage(breakpoint, message, debugProcess);
+ XDebugSession session = debugProcess.getSession().getXDebugSession();
+ XBreakpointManagerImpl manager = XDebuggerManager.getInstance(myProject).getBreakpointManager() instanceof XBreakpointManagerImpl managerImpl ? managerImpl : null;
+ if (session != null && manager != null) {
+ manager.fireBreakpointLogMessage(breakpoint.getXBreakpoint(), session, message);
+ }
}
}
diff --git a/platform/xdebugger-api/api-dump-experimental.txt b/platform/xdebugger-api/api-dump-experimental.txt
index 865c3f3c3940..4556031a5bf8 100644
--- a/platform/xdebugger-api/api-dump-experimental.txt
+++ b/platform/xdebugger-api/api-dump-experimental.txt
@@ -1,7 +1,33 @@
+*f:com.intellij.xdebugger.BreakpointErrorData
+-
+ * Currently supported only for JVM debugger
+ */
+ @ApiStatus.Experimental
+ default void breakpointError(@NotNull B breakpoint, @NotNull XDebugSession session, @NotNull BreakpointErrorData error) {
+ }
+
+ /**
+ * Called when a breakpoint with a log expression is hit
+ *
+ * Currently supported only for JVM debugger
+ */
+ @ApiStatus.Experimental
+ default void breakpointLogMessage(@NotNull B breakpoint, @NotNull XDebugSession session, @NotNull String message) {
+ }
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointManagerImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointManagerImpl.java
index 474c1220b858..4225dc16d2e0 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointManagerImpl.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointManagerImpl.java
@@ -31,6 +31,7 @@ import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.MultiMap;
import com.intellij.util.messages.SimpleMessageBusConnection;
import com.intellij.util.ui.UIUtil;
+import com.intellij.xdebugger.BreakpointErrorData;
import com.intellij.xdebugger.SplitDebuggerMode;
import com.intellij.xdebugger.XDebugSession;
import com.intellij.xdebugger.XDebuggerUtil;
@@ -286,6 +287,22 @@ public final class XBreakpointManagerImpl implements XBreakpointManager {
}
}
+ public void fireBreakpointError(@NotNull XBreakpoint> breakpoint,
+ @NotNull XDebugSession session,
+ @NotNull BreakpointErrorData error) {
+ if (isRegistered(breakpoint)) {
+ sendBreakpointEvent(breakpoint.getType(), listener -> listener.breakpointError(breakpoint, session, error));
+ }
+ }
+
+ public void fireBreakpointLogMessage(@NotNull XBreakpoint> breakpoint,
+ @NotNull XDebugSession session,
+ @NotNull String message) {
+ if (isRegistered(breakpoint)) {
+ sendBreakpointEvent(breakpoint.getType(), listener -> listener.breakpointLogMessage(breakpoint, session, message));
+ }
+ }
+
@Override
public void removeBreakpoint(final @NotNull XBreakpoint> breakpoint) {
removeBreakpoints(List.of(breakpoint));