package com.oracle.truffle.tools.chromeinspector.types;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;
import com.oracle.truffle.tools.utils.json.JSONObject;
import com.oracle.truffle.api.debug.DebugException;
import com.oracle.truffle.api.debug.DebugStackTraceElement;
import com.oracle.truffle.api.debug.DebugValue;
import com.oracle.truffle.api.source.SourceSection;
import com.oracle.truffle.tools.chromeinspector.InspectorExecutionContext;
import com.oracle.truffle.tools.chromeinspector.ScriptsHandler;
public final class ExceptionDetails {
private static final AtomicLong LAST_ID = new AtomicLong(0);
private final DebugException debugException;
private final String errorMessage;
private final long exceptionId;
public ExceptionDetails(DebugException debugException) {
this.debugException = debugException;
this.errorMessage = debugException.getLocalizedMessage();
this.exceptionId = LAST_ID.incrementAndGet();
}
public ExceptionDetails(String errorMessage) {
this.debugException = null;
this.errorMessage = errorMessage;
this.exceptionId = LAST_ID.incrementAndGet();
}
public JSONObject createJSON(InspectorExecutionContext context, boolean generatePreview) {
JSONObject json = new JSONObject();
json.put("exceptionId", exceptionId);
if (debugException == null || debugException.getCatchLocation() != null) {
json.put("text", "Caught");
} else {
json.put("text", "Uncaught");
}
SourceSection throwLocation = (debugException != null) ? debugException.getThrowLocation() : null;
if (throwLocation != null) {
json.put("lineNumber", throwLocation.getStartLine() - 1);
json.put("columnNumber", throwLocation.getStartColumn() - 1);
int scriptId;
ScriptsHandler sch = context.acquireScriptsHandler();
try {
scriptId = sch.getScriptId(throwLocation.getSource());
} finally {
context.releaseScriptsHandler();
}
if (scriptId >= 0) {
json.put("scriptId", Integer.toString(scriptId));
} else {
ScriptsHandler scriptsHandler = context.acquireScriptsHandler();
try {
json.put("url", scriptsHandler.getSourceURL(throwLocation.getSource()));
} finally {
context.releaseScriptsHandler();
}
}
}
if (debugException != null) {
List<DebugStackTraceElement> stack = debugException.getDebugStackTrace();
List<List<DebugStackTraceElement>> asyncStacks = debugException.getDebugAsynchronousStacks();
List<List<DebugStackTraceElement>> stacks;
if (asyncStacks.isEmpty()) {
stacks = Collections.singletonList(stack);
} else {
stacks = new ArrayList<>();
stacks.add(stack);
stacks.addAll(asyncStacks);
}
StackTrace stackTrace = new StackTrace(context, stacks);
json.put("stackTrace", stackTrace.toJSON());
}
DebugValue exceptionObject = (debugException != null) ? debugException.getExceptionObject() : null;
if (exceptionObject != null) {
RemoteObject ro = context.createAndRegister(exceptionObject, generatePreview);
json.put("exception", ro.toJSON());
} else {
JSONObject ex = new JSONObject();
ex.put("description", errorMessage);
ex.put("value", errorMessage);
ex.put("type", "string");
json.put("exception", ex);
}
json.put("executionContextId", context.getId());
return json;
}
public static void resetIDs() {
LAST_ID.set(0);
}
}