Skip to content

Commit 9a95fed

Browse files
committed
[GR-32787] PolyglotException should use interop messages to obtain exception message.
PullRequest: graal/9418
2 parents 9113f66 + 4f17f83 commit 9a95fed

File tree

2 files changed

+64
-23
lines changed

2 files changed

+64
-23
lines changed

truffle/src/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/polyglot/PolyglotExceptionTest.java

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,12 +95,29 @@
9595

9696
public class PolyglotExceptionTest extends AbstractPolyglotTest {
9797

98+
@ExportLibrary(InteropLibrary.class)
9899
@SuppressWarnings("serial")
99-
private static class TestGuestError extends AbstractTruffleException {
100+
static class TestGuestError extends AbstractTruffleException {
101+
102+
String exceptionMessage;
100103

101104
TestGuestError() {
102105
super("MyError");
103106
}
107+
108+
@ExportMessage
109+
boolean hasExceptionMessage() {
110+
return exceptionMessage != null;
111+
}
112+
113+
@ExportMessage
114+
Object getExceptionMessage() throws UnsupportedMessageException {
115+
if (exceptionMessage != null) {
116+
return exceptionMessage;
117+
} else {
118+
throw UnsupportedMessageException.create();
119+
}
120+
}
104121
}
105122

106123
@Test
@@ -588,6 +605,33 @@ public String getName() {
588605
executorService.awaitTermination(100, TimeUnit.SECONDS);
589606
}
590607

608+
@Test
609+
public void testExceptionMessage() {
610+
try (Context ctx = Context.create()) {
611+
TestGuestError guestError = new TestGuestError();
612+
guestError.exceptionMessage = "interop exception message";
613+
CauseErrorTruffleObject causeError = new CauseErrorTruffleObject();
614+
causeError.thrownError = guestError;
615+
Value throwError = ctx.asValue(causeError);
616+
try {
617+
throwError.execute();
618+
Assert.fail();
619+
} catch (PolyglotException e) {
620+
Assert.assertEquals("interop exception message", e.getMessage());
621+
Assert.assertTrue(e.isGuestException());
622+
}
623+
624+
guestError.exceptionMessage = null;
625+
try {
626+
throwError.execute();
627+
Assert.fail();
628+
} catch (PolyglotException e) {
629+
Assert.assertEquals("MyError", e.getMessage());
630+
Assert.assertTrue(e.isGuestException());
631+
}
632+
}
633+
}
634+
591635
abstract static class BaseNode extends Node {
592636
abstract Object execute(VirtualFrame frame);
593637
}

truffle/src/com.oracle.truffle.polyglot/src/com/oracle/truffle/polyglot/PolyglotExceptionImpl.java

Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ final class PolyglotExceptionImpl {
123123
this.guestFrames = TruffleStackTrace.getStackTrace(original);
124124
this.showInternalStackFrames = engine == null ? false : engine.engineOptionValues.get(PolyglotEngineOptions.ShowInternalStackFrames);
125125
Error resourceLimitError = getResourceLimitError(engine, exception);
126+
String exceptionMessage = null;
126127
InteropLibrary interop;
127128
if (allowInterop && (interop = InteropLibrary.getUncached()).isException(exception)) {
128129
try {
@@ -138,7 +139,9 @@ final class PolyglotExceptionImpl {
138139
this.exitStatus = this.exit ? interop.getExceptionExitStatus(exception) : 0;
139140
this.incompleteSource = this.syntaxError ? interop.isExceptionIncompleteSource(exception) : false;
140141
this.interrupted = (exceptionType == ExceptionType.INTERRUPT) && !this.cancelled;
141-
142+
if (interop.hasExceptionMessage(exception)) {
143+
exceptionMessage = interop.asString(interop.getExceptionMessage(exception));
144+
}
142145
if (interop.hasSourceLocation(exception)) {
143146
this.sourceLocation = newSourceSection(interop.getSourceLocation(exception));
144147
} else {
@@ -204,28 +207,22 @@ final class PolyglotExceptionImpl {
204207
}
205208
this.sourceLocation = location != null ? newSourceSection(location) : null;
206209
}
207-
if (isHostException()) {
208-
this.message = asHostException().getMessage();
209-
} else {
210-
if (internal) {
211-
this.message = exception.toString();
212-
} else {
213-
String exceptionMessage = exception.getMessage();
214-
if (exceptionMessage != null) {
215-
this.message = exceptionMessage;
216-
} else if (resourceLimitError != null) {
217-
String resourceExhaustedMessage = "Resource exhausted";
218-
if (resourceLimitError instanceof StackOverflowError) {
219-
resourceExhaustedMessage += ": Stack overflow";
220-
}
221-
if (resourceLimitError instanceof OutOfMemoryError) {
222-
resourceExhaustedMessage += ": Out of memory";
223-
}
224-
this.message = resourceExhaustedMessage;
225-
} else {
226-
this.message = null;
227-
}
210+
if (exceptionMessage == null) {
211+
exceptionMessage = isHostException() ? asHostException().getMessage() : internal ? exception.toString() : exception.getMessage();
212+
}
213+
if (exceptionMessage != null) {
214+
this.message = exceptionMessage;
215+
} else if (resourceLimitError != null) {
216+
String resourceExhaustedMessage = "Resource exhausted";
217+
if (resourceLimitError instanceof StackOverflowError) {
218+
resourceExhaustedMessage += ": Stack overflow";
228219
}
220+
if (resourceLimitError instanceof OutOfMemoryError) {
221+
resourceExhaustedMessage += ": Out of memory";
222+
}
223+
this.message = resourceExhaustedMessage;
224+
} else {
225+
this.message = null;
229226
}
230227

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

0 commit comments

Comments
 (0)