Skip to content

Commit

Permalink
[GR-32787] PolyglotException should use interop messages to obtain ex…
Browse files Browse the repository at this point in the history
…ception message.

PullRequest: graal/9418
  • Loading branch information
tzezula committed Aug 5, 2021
2 parents 9113f66 + 4f17f83 commit 9a95fed
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,29 @@

public class PolyglotExceptionTest extends AbstractPolyglotTest {

@ExportLibrary(InteropLibrary.class)
@SuppressWarnings("serial")
private static class TestGuestError extends AbstractTruffleException {
static class TestGuestError extends AbstractTruffleException {

String exceptionMessage;

TestGuestError() {
super("MyError");
}

@ExportMessage
boolean hasExceptionMessage() {
return exceptionMessage != null;
}

@ExportMessage
Object getExceptionMessage() throws UnsupportedMessageException {
if (exceptionMessage != null) {
return exceptionMessage;
} else {
throw UnsupportedMessageException.create();
}
}
}

@Test
Expand Down Expand Up @@ -588,6 +605,33 @@ public String getName() {
executorService.awaitTermination(100, TimeUnit.SECONDS);
}

@Test
public void testExceptionMessage() {
try (Context ctx = Context.create()) {
TestGuestError guestError = new TestGuestError();
guestError.exceptionMessage = "interop exception message";
CauseErrorTruffleObject causeError = new CauseErrorTruffleObject();
causeError.thrownError = guestError;
Value throwError = ctx.asValue(causeError);
try {
throwError.execute();
Assert.fail();
} catch (PolyglotException e) {
Assert.assertEquals("interop exception message", e.getMessage());
Assert.assertTrue(e.isGuestException());
}

guestError.exceptionMessage = null;
try {
throwError.execute();
Assert.fail();
} catch (PolyglotException e) {
Assert.assertEquals("MyError", e.getMessage());
Assert.assertTrue(e.isGuestException());
}
}
}

abstract static class BaseNode extends Node {
abstract Object execute(VirtualFrame frame);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ final class PolyglotExceptionImpl {
this.guestFrames = TruffleStackTrace.getStackTrace(original);
this.showInternalStackFrames = engine == null ? false : engine.engineOptionValues.get(PolyglotEngineOptions.ShowInternalStackFrames);
Error resourceLimitError = getResourceLimitError(engine, exception);
String exceptionMessage = null;
InteropLibrary interop;
if (allowInterop && (interop = InteropLibrary.getUncached()).isException(exception)) {
try {
Expand All @@ -138,7 +139,9 @@ final class PolyglotExceptionImpl {
this.exitStatus = this.exit ? interop.getExceptionExitStatus(exception) : 0;
this.incompleteSource = this.syntaxError ? interop.isExceptionIncompleteSource(exception) : false;
this.interrupted = (exceptionType == ExceptionType.INTERRUPT) && !this.cancelled;

if (interop.hasExceptionMessage(exception)) {
exceptionMessage = interop.asString(interop.getExceptionMessage(exception));
}
if (interop.hasSourceLocation(exception)) {
this.sourceLocation = newSourceSection(interop.getSourceLocation(exception));
} else {
Expand Down Expand Up @@ -204,28 +207,22 @@ final class PolyglotExceptionImpl {
}
this.sourceLocation = location != null ? newSourceSection(location) : null;
}
if (isHostException()) {
this.message = asHostException().getMessage();
} else {
if (internal) {
this.message = exception.toString();
} else {
String exceptionMessage = exception.getMessage();
if (exceptionMessage != null) {
this.message = exceptionMessage;
} else if (resourceLimitError != null) {
String resourceExhaustedMessage = "Resource exhausted";
if (resourceLimitError instanceof StackOverflowError) {
resourceExhaustedMessage += ": Stack overflow";
}
if (resourceLimitError instanceof OutOfMemoryError) {
resourceExhaustedMessage += ": Out of memory";
}
this.message = resourceExhaustedMessage;
} else {
this.message = null;
}
if (exceptionMessage == null) {
exceptionMessage = isHostException() ? asHostException().getMessage() : internal ? exception.toString() : exception.getMessage();
}
if (exceptionMessage != null) {
this.message = exceptionMessage;
} else if (resourceLimitError != null) {
String resourceExhaustedMessage = "Resource exhausted";
if (resourceLimitError instanceof StackOverflowError) {
resourceExhaustedMessage += ": Stack overflow";
}
if (resourceLimitError instanceof OutOfMemoryError) {
resourceExhaustedMessage += ": Out of memory";
}
this.message = resourceExhaustedMessage;
} else {
this.message = null;
}

// late materialization of host frames. only needed if polyglot exceptions cross the
Expand Down

0 comments on commit 9a95fed

Please sign in to comment.