Skip to content

Commit 801ad72

Browse files
committed
Print non-Python exceptions in TopLevelExceptionHandler only if AlwaysRunExcepthook
* Fixes #298
1 parent 7aee0d6 commit 801ad72

File tree

6 files changed

+59
-19
lines changed

6 files changed

+59
-19
lines changed

graalpython/com.oracle.graal.python.test.integration/src/com/oracle/graal/python/test/integration/PythonTests.java

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import static org.hamcrest.CoreMatchers.containsString;
2929
import static org.junit.Assert.assertEquals;
3030
import static org.junit.Assert.assertTrue;
31+
import static org.junit.Assert.fail;
3132

3233
import java.io.ByteArrayOutputStream;
3334
import java.io.File;
@@ -38,6 +39,7 @@
3839
import java.io.PrintStream;
3940
import java.util.Collections;
4041
import java.util.Map;
42+
import java.util.function.Consumer;
4143

4244
import org.graalvm.polyglot.Context;
4345
import org.graalvm.polyglot.Engine;
@@ -134,6 +136,13 @@ public static void assertPrints(String expected, Source code) {
134136
assertEquals(expected.replaceAll(" at 0x[0-9a-f]*>", " at 0xabcd>"), result.replaceAll(" at 0x[0-9a-f]*>", " at 0xabcd>"));
135137
}
136138

139+
public static void assertPrintsToStdErr(String expected, String code) {
140+
final ByteArrayOutputStream byteArray = new ByteArrayOutputStream();
141+
PythonTests.runScript(new String[0], code, System.out, byteArray);
142+
String result = byteArray.toString().replaceAll("\r\n", "\n");
143+
assertEquals(expected.replaceAll(" at 0x[0-9a-f]*>", " at 0xabcd>"), result.replaceAll(" at 0x[0-9a-f]*>", " at 0xabcd>"));
144+
}
145+
137146
public static Value eval(String code) {
138147
final ByteArrayOutputStream byteArray = new ByteArrayOutputStream();
139148
final PrintStream printStream = new PrintStream(byteArray);
@@ -218,16 +227,24 @@ public static Value runScript(Map<String, String> options, String[] args, String
218227
}
219228

220229
public static void runThrowableScript(String[] args, String source, OutputStream out, OutputStream err) {
221-
try {
222-
enterContext(args);
223-
context.eval(createSource(source));
224-
} catch (PolyglotException t) {
230+
runThrowableScript(args, source, out, err, e -> {
225231
try {
226232
Value printExc = context.eval(PRINT_EXC_TO_STDERR);
227-
printExc.execute(t.getGuestObject());
233+
printExc.execute(e.getGuestObject());
228234
} catch (Throwable ex) {
229235
throw new RuntimeException("Error while printing the PolyglotException message to stderr.", ex);
230236
}
237+
});
238+
}
239+
240+
public static void runThrowableScript(String[] args, String source, OutputStream out, OutputStream err,
241+
Consumer<PolyglotException> exceptionHandler) {
242+
try {
243+
enterContext(args);
244+
context.eval(createSource(source));
245+
fail("The eval() should throw");
246+
} catch (PolyglotException t) {
247+
exceptionHandler.accept(t);
231248
} finally {
232249
flush(out, err);
233250
closeContext();

graalpython/com.oracle.graal.python.test.integration/src/com/oracle/graal/python/test/integration/builtin/BaseExceptionTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0

graalpython/com.oracle.graal.python.test.integration/src/com/oracle/graal/python/test/integration/interop/JavaInteropTest.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
import java.io.IOException;
5151
import java.io.UnsupportedEncodingException;
5252
import java.math.BigInteger;
53+
import java.nio.charset.StandardCharsets;
5354
import java.util.ArrayList;
5455
import java.util.Arrays;
5556
import java.util.HashMap;
@@ -67,6 +68,7 @@
6768
import org.graalvm.polyglot.proxy.ProxyHashMap;
6869
import org.graalvm.polyglot.proxy.ProxyObject;
6970
import org.junit.After;
71+
import org.junit.Assert;
7072
import org.junit.Before;
7173
import org.junit.Ignore;
7274
import org.junit.Test;
@@ -93,6 +95,7 @@ public void setUpTest() {
9395
Builder builder = Context.newBuilder();
9496
builder.allowExperimentalOptions(true);
9597
builder.allowAllAccess(true);
98+
builder.option("engine.WarnInterpreterOnly", "false");
9699
builder.out(out);
97100
builder.err(err);
98101
context = builder.build();
@@ -197,6 +200,24 @@ public void truffleMethodExport() {
197200
assertTrue(main.canExecute());
198201
}
199202

203+
// From https://github.com/oracle/graalpython/issues/298
204+
@Test
205+
public void testHostException() {
206+
try {
207+
context.eval(createSource("import java; java.math.BigInteger.ONE.divide(java.math.BigInteger.ZERO)"));
208+
fail();
209+
} catch (PolyglotException e) {
210+
Assert.assertTrue(e.isHostException());
211+
Assert.assertTrue(e.asHostException() instanceof ArithmeticException);
212+
Assert.assertTrue(e.getMessage(), e.getMessage().contains("divide by zero"));
213+
}
214+
215+
String outString = out.toString(StandardCharsets.UTF_8);
216+
String errString = err.toString(StandardCharsets.UTF_8);
217+
Assert.assertTrue(outString, outString.isEmpty());
218+
Assert.assertTrue(errString, errString.isEmpty());
219+
}
220+
200221
@Test
201222
public void javaArraySet() {
202223
String source = "import java\n" +

graalpython/com.oracle.graal.python.test.integration/src/com/oracle/graal/python/test/integration/module/PosixTest.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2017, 2023, Oracle and/or its affiliates.
2+
* Copyright (c) 2017, 2024, Oracle and/or its affiliates.
33
* Copyright (c) 2013, Regents of the University of California
44
*
55
* All rights reserved.
@@ -25,9 +25,9 @@
2525
*/
2626
package com.oracle.graal.python.test.integration.module;
2727

28-
import static com.oracle.graal.python.test.integration.PythonTests.assertLastLineError;
2928
import static com.oracle.graal.python.test.integration.PythonTests.assertLastLineErrorContains;
3029
import static com.oracle.graal.python.test.integration.PythonTests.assertPrints;
30+
import static com.oracle.graal.python.test.integration.PythonTests.assertPrintsToStdErr;
3131
import static com.oracle.graal.python.test.integration.Utils.IS_WINDOWS;
3232
import static org.junit.Assert.assertEquals;
3333
import static org.junit.Assert.assertTrue;
@@ -177,7 +177,7 @@ public void stdout() {
177177
@Test
178178
public void stderr() {
179179
assumeFalse(IS_WINDOWS);
180-
assertLastLineError("error\n", "import sys; sys.stderr.write('error\\n')");
180+
assertPrintsToStdErr("error\n", "import sys; sys.stderr.write('error\\n')");
181181
}
182182

183183
@Test
@@ -189,7 +189,7 @@ public void printToStdout() {
189189
@Test
190190
public void printToStderr() {
191191
assumeFalse(IS_WINDOWS);
192-
assertLastLineError("1-2...", "import sys; print('1', '2', sep='-', file=sys.stderr, end='...', flush=True)");
192+
assertPrintsToStdErr("1-2...", "import sys; print('1', '2', sep='-', file=sys.stderr, end='...', flush=True)");
193193
}
194194

195195
@Test

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/exception/TopLevelExceptionHandler.java

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -213,16 +213,18 @@ private void handleJavaException(Throwable e) {
213213
if (pe != null) {
214214
throw handlePythonException(pe);
215215
}
216-
try {
217-
boolean exitException = InteropLibrary.getUncached().isException(e) && InteropLibrary.getUncached().getExceptionType(e) == ExceptionType.EXIT;
218-
if (!exitException) {
219-
ExceptionUtils.printPythonLikeStackTrace(getContext(), e);
220-
if (PythonOptions.shouldPrintJavaStacktrace(getPythonLanguage(), e)) {
221-
e.printStackTrace();
216+
if (getContext().getOption(PythonOptions.AlwaysRunExcepthook)) {
217+
try {
218+
boolean exitException = InteropLibrary.getUncached().isException(e) && InteropLibrary.getUncached().getExceptionType(e) == ExceptionType.EXIT;
219+
if (!exitException) {
220+
ExceptionUtils.printPythonLikeStackTrace(getContext(), e);
221+
if (PythonOptions.shouldPrintJavaStacktrace(getPythonLanguage(), e)) {
222+
e.printStackTrace();
223+
}
222224
}
225+
} catch (UnsupportedMessageException unsupportedMessageException) {
226+
throw CompilerDirectives.shouldNotReachHere();
223227
}
224-
} catch (UnsupportedMessageException unsupportedMessageException) {
225-
throw CompilerDirectives.shouldNotReachHere();
226228
}
227229
}
228230

mx.graalpython/suite.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -453,7 +453,7 @@
453453
"spotbugsIgnoresGenerated": True,
454454
},
455455

456-
# GRAALPYTHON TESTS
456+
# GRAALPYTHON_UNIT_TESTS
457457
"com.oracle.graal.python.test": {
458458
"subDir": "graalpython",
459459
"sourceDirs": ["src"],

0 commit comments

Comments
 (0)