mirror of
https://github.com/wgh136/flutter_qjs.git
synced 2025-09-27 05:27:23 +00:00
host promise rejection
This commit is contained in:
@@ -19,6 +19,9 @@ typedef JsMethodHandler = dynamic Function(String method, List args);
|
||||
/// Handler function to manage js module.
|
||||
typedef JsModuleHandler = String Function(String name);
|
||||
|
||||
/// Handler to manage unhandled promise rejection.
|
||||
typedef JsHostPromiseRejectionHandler = void Function(String reason);
|
||||
|
||||
class FlutterQjs {
|
||||
Pointer _rt;
|
||||
Pointer _ctx;
|
||||
@@ -35,10 +38,17 @@ class FlutterQjs {
|
||||
/// Handler function to manage js module.
|
||||
JsModuleHandler moduleHandler;
|
||||
|
||||
/// Handler function to manage js module.
|
||||
JsHostPromiseRejectionHandler hostPromiseRejectionHandler;
|
||||
|
||||
/// Quickjs engine for flutter.
|
||||
///
|
||||
/// Pass handlers to implement js-dart interaction and resolving modules.
|
||||
FlutterQjs({this.methodHandler, this.moduleHandler, this.stackSize});
|
||||
FlutterQjs(
|
||||
{this.methodHandler,
|
||||
this.moduleHandler,
|
||||
this.stackSize,
|
||||
this.hostPromiseRejectionHandler});
|
||||
|
||||
_ensureEngine() {
|
||||
if (_rt != null) return;
|
||||
@@ -51,14 +61,22 @@ class FlutterQjs {
|
||||
runtimeOpaques[rt]?.ref?.remove(obj);
|
||||
return Pointer.fromAddress(0);
|
||||
}
|
||||
if (argv.address != 0 && method.address != 0) {
|
||||
if (argv.address != 0) {
|
||||
if (method.address == ctx.address) {
|
||||
final errStr = parseJSException(ctx, perr: argv);
|
||||
if (hostPromiseRejectionHandler != null) {
|
||||
hostPromiseRejectionHandler(errStr);
|
||||
} else {
|
||||
print("unhandled promise rejection: $errStr");
|
||||
}
|
||||
return Pointer.fromAddress(0);
|
||||
}
|
||||
if (methodHandler == null) throw Exception("No MethodHandler");
|
||||
var argvs = jsToDart(ctx, argv);
|
||||
return dartToJs(
|
||||
ctx,
|
||||
methodHandler(
|
||||
Utf8.fromUtf8(method.cast<Utf8>()),
|
||||
argvs,
|
||||
jsToDart(ctx, argv),
|
||||
));
|
||||
}
|
||||
if (moduleHandler == null) throw Exception("No ModuleHandler");
|
||||
@@ -69,11 +87,20 @@ class FlutterQjs {
|
||||
});
|
||||
return ret;
|
||||
} catch (e, stack) {
|
||||
final errStr = e.toString() + "\n" + stack.toString();
|
||||
if (method.address == 0) {
|
||||
print("DartObject release error: " + errStr);
|
||||
return Pointer.fromAddress(0);
|
||||
}
|
||||
if (method.address == ctx.address) {
|
||||
print("host Promise Rejection Handler error: " + errStr);
|
||||
return Pointer.fromAddress(0);
|
||||
}
|
||||
var err = jsThrowInternalError(
|
||||
ctx,
|
||||
e.toString() + "\n" + stack.toString(),
|
||||
errStr,
|
||||
);
|
||||
if (method.address == 0) {
|
||||
if (argv.address == 0) {
|
||||
jsFreeValue(ctx, err);
|
||||
return Pointer.fromAddress(0);
|
||||
}
|
||||
|
@@ -143,12 +143,17 @@ dynamic _decodeData(dynamic data, SendPort port,
|
||||
|
||||
void _runJsIsolate(Map spawnMessage) async {
|
||||
SendPort sendPort = spawnMessage['port'];
|
||||
JsMethodHandler methodHandler = spawnMessage['handler'];
|
||||
ReceivePort port = ReceivePort();
|
||||
sendPort.send(port.sendPort);
|
||||
var qjs = FlutterQjs(
|
||||
stackSize: spawnMessage['stackSize'],
|
||||
methodHandler: methodHandler,
|
||||
hostPromiseRejectionHandler: (reason) {
|
||||
sendPort.send({
|
||||
'type': 'hostPromiseRejection',
|
||||
'reason': reason,
|
||||
});
|
||||
},
|
||||
methodHandler: spawnMessage['handler'],
|
||||
moduleHandler: (name) {
|
||||
var ptr = allocate<Pointer<Utf8>>();
|
||||
ptr.value = Pointer.fromAddress(0);
|
||||
@@ -222,11 +227,19 @@ class IsolateQjs {
|
||||
/// Asynchronously handler to manage js module.
|
||||
JsAsyncModuleHandler moduleHandler;
|
||||
|
||||
/// Handler function to manage js module.
|
||||
JsHostPromiseRejectionHandler hostPromiseRejectionHandler;
|
||||
|
||||
/// Quickjs engine runing on isolate thread.
|
||||
///
|
||||
/// Pass handlers to implement js-dart interaction and resolving modules. The `methodHandler` is
|
||||
/// used in isolate, so **the handler function must be a top-level function or a static method**.
|
||||
IsolateQjs({this.methodHandler, this.moduleHandler, this.stackSize});
|
||||
IsolateQjs({
|
||||
this.methodHandler,
|
||||
this.moduleHandler,
|
||||
this.stackSize,
|
||||
this.hostPromiseRejectionHandler,
|
||||
});
|
||||
|
||||
_ensureEngine() {
|
||||
if (_sendPort != null) return;
|
||||
@@ -247,6 +260,21 @@ class IsolateQjs {
|
||||
return;
|
||||
}
|
||||
switch (msg['type']) {
|
||||
case 'hostPromiseRejection':
|
||||
try {
|
||||
final errStr = msg['reason'];
|
||||
if (hostPromiseRejectionHandler != null) {
|
||||
hostPromiseRejectionHandler(errStr);
|
||||
} else {
|
||||
print("unhandled promise rejection: $errStr");
|
||||
}
|
||||
} catch (e, stack) {
|
||||
print("host Promise Rejection Handler error: " +
|
||||
e.toString() +
|
||||
"\n" +
|
||||
stack.toString());
|
||||
}
|
||||
break;
|
||||
case 'module':
|
||||
var ptr = Pointer<Pointer>.fromAddress(msg['ptr']);
|
||||
try {
|
||||
|
@@ -78,10 +78,12 @@ class JSPromise extends JSRefValue {
|
||||
return true;
|
||||
}
|
||||
if (status["__rejected"] == true) {
|
||||
final err = jsGetPropertyStr(ctx, val, "__error");
|
||||
completer.completeError(parseJSException(
|
||||
ctx,
|
||||
e: jsGetPropertyStr(ctx, val, "__error"),
|
||||
perr: err,
|
||||
));
|
||||
jsFreeValue(ctx, err);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -129,8 +131,9 @@ Pointer jsGetPropertyStr(Pointer ctx, Pointer val, String prop) {
|
||||
return jsProp;
|
||||
}
|
||||
|
||||
String parseJSException(Pointer ctx, {Pointer e}) {
|
||||
e = e ?? jsGetException(ctx);
|
||||
String parseJSException(Pointer ctx, {Pointer perr}) {
|
||||
final e = perr ?? jsGetException(ctx);
|
||||
|
||||
var err = jsToCString(ctx, e);
|
||||
if (jsValueGetTag(e) == JSTag.OBJECT) {
|
||||
Pointer stack = jsGetPropertyStr(ctx, e, "stack");
|
||||
@@ -139,7 +142,7 @@ String parseJSException(Pointer ctx, {Pointer e}) {
|
||||
}
|
||||
jsFreeValue(ctx, stack);
|
||||
}
|
||||
jsFreeValue(ctx, e);
|
||||
if (perr == null) jsFreeValue(ctx, e);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user