1- import 'dart:async' ;
21import 'dart:js_interop' ;
32import 'dart:js_interop_unsafe' ;
43import 'dart:typed_data' ;
@@ -64,13 +63,15 @@ class _UniqueFieldNames {
6463 static const onlyOpenVfs = 'o' ;
6564 static const parameters = 'p' ;
6665 static const storageMode = 's' ;
66+ static const serializedExceptionType = 's' ;
6767 static const sql = 's' ; // not used in same message
6868 static const type = 't' ;
6969 static const wasmUri = 'u' ;
7070 static const updateTableName = 'u' ;
7171 static const responseData = 'r' ;
7272 static const returnRows = 'r' ;
7373 static const updateRowId = 'r' ;
74+ static const serializedException = 'r' ;
7475 static const rows = 'r' ; // no clash, used on different message types
7576 static const typeVector = 'v' ;
7677}
@@ -162,14 +163,6 @@ sealed class Request extends Message {
162163 object[_UniqueFieldNames .databaseId] = id.toJS;
163164 }
164165 }
165-
166- Future <Response > tryRespond (FutureOr <Response > Function () function) async {
167- try {
168- return await function ();
169- } catch (e) {
170- return ErrorResponse (message: e.toString (), requestId: requestId);
171- }
172- }
173166}
174167
175168sealed class Response extends Message {
@@ -767,12 +760,33 @@ final class RowsResponse extends Response {
767760final class ErrorResponse extends Response {
768761 final String message;
769762
770- ErrorResponse ({required this .message, required super .requestId});
763+ /// We can't send Dart objects over web channels, but we're serializing the
764+ /// most common exception types so that we can reconstruct them on the other
765+ /// end.
766+ final Object ? serializedException;
767+
768+ ErrorResponse ({
769+ required this .message,
770+ required super .requestId,
771+ this .serializedException,
772+ });
771773
772774 factory ErrorResponse .deserialize (JSObject object) {
775+ Object ? serializedException;
776+ if (object.has (_UniqueFieldNames .serializedExceptionType)) {
777+ serializedException = switch (
778+ (object[_UniqueFieldNames .serializedExceptionType] as JSNumber )
779+ .toDartInt) {
780+ _typeSqliteException => deserializeSqliteException (
781+ object[_UniqueFieldNames .serializedException] as JSArray ),
782+ _ => null ,
783+ };
784+ }
785+
773786 return ErrorResponse (
774787 message: (object[_UniqueFieldNames .errorMessage] as JSString ).toDart,
775788 requestId: object.requestId,
789+ serializedException: serializedException,
776790 );
777791 }
778792
@@ -783,12 +797,70 @@ final class ErrorResponse extends Response {
783797 void serialize (JSObject object, List <JSObject > transferred) {
784798 super .serialize (object, transferred);
785799 object[_UniqueFieldNames .errorMessage] = message.toJS;
800+
801+ if (serializedException case final SqliteException e? ) {
802+ object[_UniqueFieldNames .serializedExceptionType] =
803+ _typeSqliteException.toJS;
804+ object[_UniqueFieldNames .serializedException] =
805+ serializeSqliteException (e);
806+ }
786807 }
787808
788809 @override
789810 RemoteException interpretAsError () {
790- return RemoteException (message: message);
811+ return RemoteException (message: message, exception: serializedException);
812+ }
813+
814+ static SqliteException deserializeSqliteException (JSArray data) {
815+ final [
816+ message,
817+ explanation,
818+ extendedResultCode,
819+ operation,
820+ causingStatement,
821+ paramData,
822+ paramTypes,
823+ ..._,
824+ ] = data.toDart;
825+
826+ String ? decodeNullableString (JSAny ? jsValue) {
827+ if (jsValue.isDefinedAndNotNull) {
828+ return (jsValue as JSString ).toDart;
829+ }
830+ return null ;
831+ }
832+
833+ return SqliteException (
834+ (extendedResultCode as JSNumber ).toDartInt,
835+ (message as JSString ).toDart,
836+ decodeNullableString (explanation),
837+ decodeNullableString (causingStatement),
838+ paramData.isDefinedAndNotNull && paramTypes.isDefinedAndNotNull
839+ ? TypeCode .decodeValues (
840+ paramData as JSArray , paramTypes as JSArrayBuffer )
841+ : null ,
842+ decodeNullableString (operation),
843+ );
844+ }
845+
846+ static JSArray serializeSqliteException (SqliteException e) {
847+ final params = switch (e.parametersToStatement) {
848+ null => null ,
849+ final parameters => TypeCode .encodeValues (parameters),
850+ };
851+
852+ return [
853+ e.message.toJS,
854+ e.explanation? .toJS,
855+ e.extendedResultCode.toJS,
856+ e.operation? .toJS,
857+ e.causingStatement? .toJS,
858+ params? .$1,
859+ params? .$2,
860+ ].toJS;
791861 }
862+
863+ static const _typeSqliteException = 0 ;
792864}
793865
794866final class StreamRequest extends Request {
0 commit comments