IJPL-237338 Listener method to subscribe on breakpoints with log events

IJPL-237326 Extension point to override behavior when conditional breakpoint has invalid expression


(cherry picked from commit a7e82eea60845ed1b82a1afd135eed259c58dfa9)

IJ-MR-194396

GitOrigin-RevId: 10e9e10be253c82398c91b8858d871ff238819b0
This commit is contained in:
Artem.Bukhonov
2026-03-04 19:39:37 +00:00
committed by intellij-monorepo-bot
parent bd81862d9d
commit 5aeb1d80a4
9 changed files with 211 additions and 5 deletions
@@ -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) {
@@ -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<P extends JavaBreakpointProperties> 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");
}
@@ -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);
}
}
}