Bug 1052158 - Forward the GeckoRequest error stack to Java. r=wesj

This commit is contained in:
Brian Nicholson 2014-11-19 16:33:56 -08:00
parent 5bdf9eae23
commit 57852448b5
4 changed files with 30 additions and 24 deletions

View File

@ -228,6 +228,7 @@ public class GeckoAppShell
private static Sensor gLightSensor;
private static final String GECKOREQUEST_RESPONSE_KEY = "response";
private static final String GECKOREQUEST_ERROR_KEY = "error";
/*
* Keep in sync with constants found here:
@ -434,7 +435,7 @@ public class GeckoAppShell
public void handleMessage(String event, NativeJSObject message, EventCallback callback) {
EventDispatcher.getInstance().unregisterGeckoThreadListener(this, event);
if (!message.has(GECKOREQUEST_RESPONSE_KEY)) {
request.onError();
request.onError(message.getObject(GECKOREQUEST_ERROR_KEY));
return;
}
request.onResponse(message.getObject(GECKOREQUEST_RESPONSE_KEY));

View File

@ -96,7 +96,7 @@ public class testGeckoRequest extends UITest {
}
@Override
public void onError() {
public void onError(NativeJSObject error) {
errorReceived.set(true);
}
});

View File

@ -1,3 +1,6 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.gecko.util;
import java.util.concurrent.atomic.AtomicInteger;
@ -77,15 +80,15 @@ public abstract class GeckoRequest {
/**
* Callback executed when the request fails.
*
* In general, this should not be overridden since there's no way to differentiate between
* expected errors and logic errors in JS. If the Gecko-side request handler wants to send a
* recoverable error to Java, it should include any error data in the response object that the
* {@link #onResponse(NativeJSObject)} callback can handle as necessary.
* By default, an exception is thrown. This should be overridden if the
* GeckoRequest is able to recover from the error.
*
* @throws RuntimeException
*/
@RobocopTarget
public void onError() {
throw new RuntimeException("Unhandled error for GeckoRequest: " + name);
public void onError(NativeJSObject error) {
final String message = error.optString("message", "<no message>");
final String stack = error.optString("stack", "<no stack>");
throw new RuntimeException("Unhandled error for GeckoRequest " + name + ": " + message + "\nJS stack:\n" + stack);
}
}
}

View File

@ -143,24 +143,26 @@ let requestHandler = {
let wrapper = JSON.parse(aData);
let listener = this._listeners[aTopic];
// A null response indicates an error. If an error occurs in the callback
// below, the response will remain null, and Java will fire onError for
// this request.
let response = null;
try {
let result = yield listener(wrapper.data);
if (typeof result !== "object" || result === null) {
let response = yield listener(wrapper.data);
if (typeof response !== "object" || response === null) {
throw new Error("Gecko request listener did not return an object");
}
response = result;
} catch (e) {
Cu.reportError(e);
}
Messaging.sendRequest({
type: "Gecko:Request" + wrapper.id,
response: response
});
Messaging.sendRequest({
type: "Gecko:Request" + wrapper.id,
response: response
});
} catch (e) {
Cu.reportError("Error in Messaging handler for " + aTopic + ": " + e);
Messaging.sendRequest({
type: "Gecko:Request" + wrapper.id,
error: {
message: e.message || (e && e.toString()),
stack: e.stack || Components.stack.formattedStack,
}
});
}
})
};