exception handlers should also handle Throwables

Reviewed-by: batsatt
This commit is contained in:
akhil 2014-01-28 13:49:43 -08:00
parent a9136f94d9
commit c4cf66369e
6 changed files with 61 additions and 44 deletions

View File

@ -110,7 +110,7 @@ public final class Server {
initAssertionStatus();
}
public static void main(final String... args) throws Exception {
public static void main(final String... args) throws Throwable {
new Server().run(args);
}
@ -136,7 +136,7 @@ public final class Server {
final String workDir,
final ScriptContext context,
final int instanceNumber,
final ThreadPool threadPool) throws Exception {
final ThreadPool threadPool) {
this.engine = engine;
this.context = context;
this.bindings = context.getBindings(ScriptContext.ENGINE_SCOPE);
@ -150,7 +150,7 @@ public final class Server {
this.holder = new SecureHolder(eventLoop, loader, (Invocable) engine);
}
public void run(final String... args) throws ServerException {
public void run(final String... args) throws Throwable {
// No Server instance can be accessed from user scripts.
// Although this public method is not accessible, do a permission check.
checkPermission();
@ -191,7 +191,7 @@ public final class Server {
}
}
private void runUserScripts() throws Exception {
private void runUserScripts() throws Throwable {
assert userFile != null;
final String[] userFiles = {userFile};
@ -200,7 +200,7 @@ public final class Server {
userFiles);
}
private void runREPL() throws Exception {
private void runREPL() throws Throwable {
runEventLoop(EMPTY_ARRAY, EMPTY_ARRAY, EMPTY_ARRAY);
}
@ -209,19 +209,20 @@ public final class Server {
"--print".equals(arg) || "-pe".equals(arg) || "-p".equals(arg));
}
private void runEval() throws Exception {
runEventLoop(avatarArgs.toArray(new String[avatarArgs.size()]),
private void runEval() throws Throwable {
runEventLoop(
avatarArgs.toArray(new String[avatarArgs.size()]),
userArgs.toArray(new String[userArgs.size()]),
EMPTY_ARRAY);
}
private void runEventLoop(final String[] avatarArgs, final String[] userArgs, final String[] userFiles) throws Exception {
Exception rootCause = null;
private void runEventLoop(final String[] avatarArgs, final String[] userArgs, final String[] userFiles) throws Throwable {
Throwable rootCause = null;
holder.setArgs(avatarArgs, userArgs, userFiles);
try {
runSystemScript(SYSTEM_INIT_SCRIPTS);
} catch(Exception ex) {
} catch (Throwable ex) {
if (!eventLoop.handleCallbackException(ex)) {
rootCause = ex;
throw ex;
@ -231,7 +232,7 @@ public final class Server {
try {
// emit the process.exit event
runSystemScript(SYSTEM_FINALIZATION_SCRIPTS);
} catch (Exception ex) {
} catch (Throwable ex) {
if (!eventLoop.handleCallbackException(ex)) {
rootCause.addSuppressed(ex);
throw rootCause;
@ -243,7 +244,7 @@ public final class Server {
// the process can continue. For example some timer events can be fired.
try {
eventLoop.run();
} catch(Exception ex) {
} catch (Throwable ex) {
boolean rethrow = false;
if (!eventLoop.handleCallbackException(ex)) {
rethrow = true;
@ -258,7 +259,7 @@ public final class Server {
try {
// emit the process.exit event
runSystemScript(SYSTEM_FINALIZATION_SCRIPTS);
} catch (Exception ex) {
} catch (Throwable ex) {
if (rootCause != null) {
rootCause.addSuppressed(ex);
throw rootCause;

View File

@ -38,14 +38,15 @@ import com.oracle.libuv.NativeException;
* are not filtered out. The cause of this exception is the originally thrown
* exception.
*/
public final class ServerException extends Exception {
public final class ServerException extends Throwable {
private static final long serialVersionUID = 8930713476760671228L;
private final Throwable orig;
private final StackTraceElement[] elems;
private final NashornException nex;
ServerException(Throwable orig) {
ServerException(final Throwable orig) {
// No LibUV NativeException should be received,
// these are translated by wrap scripts onto native JS Error.
assert !(orig instanceof NativeException);

View File

@ -72,7 +72,7 @@ public final class EventLoop {
private Callback isHandlerRegistered = null;
private Callback uncaughtExceptionHandler = null;
private Exception pendingException = null;
private Throwable pendingException = null;
private boolean syncEventsProcessing = true;
private ScriptObjectMirror domain;
@ -132,13 +132,13 @@ public final class EventLoop {
eventQueue.add(event);
}
public void run() throws Exception {
public void run() throws Throwable {
assert Thread.currentThread() == mainThread : "called from non-event thread " + Thread.currentThread().getName();
executor.allowCoreThreadTimeOut(true);
uvLoop.run();
// throw pending exception, if any
if (pendingException != null) {
final Exception pex = pendingException;
final Throwable pex = pendingException;
pendingException = null;
throw pex;
}
@ -229,7 +229,7 @@ public final class EventLoop {
private static final String UNCAUGHT_EXCEPTION_NAME = "uncaughtException";
public boolean handleCallbackException(final Exception ex) {
public boolean handleCallbackException(final Throwable ex) {
boolean handled = true;
// callback to check if an uncaught exception handler has been registered by the user
final Object[] registeredArgs = {null};
@ -358,7 +358,7 @@ public final class EventLoop {
final Logging logging,
final String workDir,
final int instanceNumber,
final ThreadPool executor) throws IOException {
final ThreadPool executor) {
mainThread = Thread.currentThread();
final String uv = LibUV.version();
if (!uvVersion.equals(uv)) {
@ -376,7 +376,7 @@ public final class EventLoop {
this.uvLoop = new LoopHandle(new CallbackExceptionHandler() {
@Override
public void handle(final Exception ex) {
public void handle(final Throwable ex) {
if (!handleCallbackException(ex)) {
if (pendingException == null) {
pendingException = ex;

View File

@ -34,7 +34,7 @@ import org.testng.annotations.Test;
public class EventLoopTest {
@Test
public void testEventLoop() throws Exception {
public void testEventLoop() throws Throwable {
File dir = new File("src/test/js/eventloop/");
boolean failed = false;
for (File f : dir.listFiles()) {

View File

@ -25,6 +25,8 @@
import java.io.File;
import java.io.FilePermission;
import java.lang.Exception;
import java.lang.Throwable;
import java.net.SocketPermission;
import java.net.URL;
import java.nio.file.FileSystems;
@ -140,7 +142,7 @@ public class PermissionTest {
}
@Test
public void testTCPNoAuth() throws Exception {
public void testTCPNoAuth() throws Throwable {
int port = getPort();
File f = new File("src/test/js/security/tcp.js");
Map<String, Object> bindings = new HashMap<String, Object>();
@ -150,7 +152,7 @@ public class PermissionTest {
}
@Test
public void testTCPNoAccept() throws Exception {
public void testTCPNoAccept() throws Throwable {
int port = getPort();
File f = new File("src/test/js/security/tcp.js");
Map<String, Object> bindings = new HashMap<String, Object>();
@ -163,7 +165,7 @@ public class PermissionTest {
}
@Test
public void testTCPNoConnect() throws Exception {
public void testTCPNoConnect() throws Throwable {
int port = getPort();
File f = new File("src/test/js/security/tcp.js");
Map<String, Object> bindings = new HashMap<String, Object>();
@ -175,7 +177,7 @@ public class PermissionTest {
}
@Test
public void testTCPAuth() throws Exception {
public void testTCPAuth() throws Throwable {
int port = getPort();
Permissions permissions = new Permissions();
permissions.add(new SocketPermission(ADDRESS + ":" + port, "listen"));
@ -190,7 +192,7 @@ public class PermissionTest {
}
@Test
public void testUDPNoAuth() throws Exception {
public void testUDPNoAuth() throws Throwable {
int port = getPort();
File f = new File("src/test/js/security/udp.js");
Map<String, Object> bindings = new HashMap<String, Object>();
@ -201,7 +203,7 @@ public class PermissionTest {
}
@Test
public void testUDPAuth() throws Exception {
public void testUDPAuth() throws Throwable {
int port = getPort();
Permissions permissions = new Permissions();
// required by dns.js
@ -216,7 +218,7 @@ public class PermissionTest {
}
@Test
public void testSpawnNoAuth() throws Exception {
public void testSpawnNoAuth() throws Throwable {
File f = new File("src/test/js/security/spawn.js");
Map<String, Object> bindings = new HashMap<String, Object>();
// exePath
@ -230,7 +232,7 @@ public class PermissionTest {
}
@Test
public void testSpawnAuth() throws Exception {
public void testSpawnAuth() throws Throwable {
Permissions permissions = new Permissions();
permissions.add(new PropertyPermission("java.class.path", "read"));
permissions.add(new PropertyPermission("java.library.path", "read"));
@ -246,7 +248,7 @@ public class PermissionTest {
}
@Test
public void testPipeNoAuth() throws Exception {
public void testPipeNoAuth() throws Throwable {
File f = new File("src/test/js/security/pipe.js");
final String PIPE_NAME;
@ -266,7 +268,7 @@ public class PermissionTest {
}
@Test
public void testPipeAuth() throws Exception {
public void testPipeAuth() throws Throwable {
File f = new File("src/test/js/security/pipe.js");
final String PIPE_NAME;
@ -296,7 +298,7 @@ public class PermissionTest {
}
@Test
public void testPipeNoAccept() throws Exception {
public void testPipeNoAccept() throws Throwable {
File f = new File("src/test/js/security/pipe.js");
final String PIPE_NAME;
@ -321,7 +323,7 @@ public class PermissionTest {
}
@Test
public void testPipeNoConnect() throws Exception {
public void testPipeNoConnect() throws Throwable {
File f = new File("src/test/js/security/pipe.js");
final String PIPE_NAME;
@ -345,7 +347,7 @@ public class PermissionTest {
}
@Test
public void testModules() throws Exception {
public void testModules() throws Throwable {
File f = new File("src/test/js/security/modules.js");
Map<String, Object> bindings = new HashMap<String, Object>();
@ -355,7 +357,7 @@ public class PermissionTest {
}
@Test
public void testModules2() throws Exception {
public void testModules2() throws Throwable {
File f = new File("src/test/js/security/modules2.js");
Map<String, Object> bindings = new HashMap<String, Object>();
@ -365,14 +367,14 @@ public class PermissionTest {
}
@Test
public void testProcess() throws Exception {
public void testProcess() throws Throwable {
File f = new File("src/test/js/security/process.js");
Map<String, Object> bindings = new HashMap<String, Object>();
String osname = System.getProperty("os.name").toLowerCase();
if (osname.startsWith("windows")) {
bindings.put("__test_windows", "true");
}
doSuccess(bindings, f, new Permissions());
}
@ -408,11 +410,11 @@ public class PermissionTest {
}
}
private static void doFail(Map<String, Object> bindings, File f) throws Exception {
private static void doFail(Map<String, Object> bindings, File f) throws Throwable {
doFail(bindings, f, new Permissions());
}
private static void doFail(Map<String, Object> bindings, File f, Permissions permissions) throws Exception {
private static void doFail(Map<String, Object> bindings, File f, Permissions permissions) throws Throwable {
// Capture caller
System.err.println("Called by " + new Exception().getStackTrace()[1].getMethodName());
URL location = f.toURI().toURL();
@ -424,7 +426,13 @@ public class PermissionTest {
testFailure(new Callable() {
@Override
public Object call() throws Exception {
server.run(args);
try {
server.run(args);
} catch (Exception ex) {
throw ex;
} catch (Throwable th) {
throw new Exception(th);
}
return null;
}
});
@ -432,7 +440,7 @@ public class PermissionTest {
System.out.println(f + " NoAuth test passed");
}
private static void doSuccess(Map<String, Object> bindings, File f, Permissions permissions) throws Exception {
private static void doSuccess(Map<String, Object> bindings, File f, Permissions permissions) throws Throwable {
// Capture caller
System.err.println("Called by " + new Exception().getStackTrace()[1].getMethodName());
URL location = f.toURI().toURL();
@ -444,7 +452,13 @@ public class PermissionTest {
testSuccess(new Callable() {
@Override
public Object call() throws Exception {
server.run(args);
try {
server.run(args);
} catch (Exception ex) {
throw ex;
} catch (Throwable th) {
throw new Exception(th);
}
Object obj = engine.get(SCRIPT_OK);
if (obj == null) {
throw new Exception("TEST FAILURE");

View File

@ -45,6 +45,7 @@
package perf;
import java.lang.Throwable;
import java.nio.ByteBuffer;
import com.oracle.httpparser.HttpParser;
import com.oracle.httpparser.HttpParserSettings;
@ -67,7 +68,7 @@ public class HttpSimple {
private String[] headers;
}
public static void main(String[] args) throws Exception {
public static void main(String[] args) throws Throwable {
LibUV.cwd();
final LoopHandle loop = new LoopHandle();
final TCPHandle server = new TCPHandle(loop);