1
- import 'dart:async' ;
2
1
import 'dart:js_interop' ;
3
2
import 'dart:js_interop_unsafe' ;
4
3
import 'dart:typed_data' ;
@@ -64,13 +63,15 @@ class _UniqueFieldNames {
64
63
static const onlyOpenVfs = 'o' ;
65
64
static const parameters = 'p' ;
66
65
static const storageMode = 's' ;
66
+ static const serializedExceptionType = 's' ;
67
67
static const sql = 's' ; // not used in same message
68
68
static const type = 't' ;
69
69
static const wasmUri = 'u' ;
70
70
static const updateTableName = 'u' ;
71
71
static const responseData = 'r' ;
72
72
static const returnRows = 'r' ;
73
73
static const updateRowId = 'r' ;
74
+ static const serializedException = 'r' ;
74
75
static const rows = 'r' ; // no clash, used on different message types
75
76
static const typeVector = 'v' ;
76
77
}
@@ -162,14 +163,6 @@ sealed class Request extends Message {
162
163
object[_UniqueFieldNames .databaseId] = id.toJS;
163
164
}
164
165
}
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
- }
173
166
}
174
167
175
168
sealed class Response extends Message {
@@ -767,12 +760,33 @@ final class RowsResponse extends Response {
767
760
final class ErrorResponse extends Response {
768
761
final String message;
769
762
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
+ });
771
773
772
774
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
+
773
786
return ErrorResponse (
774
787
message: (object[_UniqueFieldNames .errorMessage] as JSString ).toDart,
775
788
requestId: object.requestId,
789
+ serializedException: serializedException,
776
790
);
777
791
}
778
792
@@ -783,12 +797,70 @@ final class ErrorResponse extends Response {
783
797
void serialize (JSObject object, List <JSObject > transferred) {
784
798
super .serialize (object, transferred);
785
799
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
+ }
786
807
}
787
808
788
809
@override
789
810
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;
791
861
}
862
+
863
+ static const _typeSqliteException = 0 ;
792
864
}
793
865
794
866
final class StreamRequest extends Request {
0 commit comments