11/**
22 * Base class for all Spacetime host errors (i.e. errors that may be thrown
33 * by database functions).
4- *
5- * Instances of SpacetimeError can be created with just an error code,
6- * which will return the appropriate subclass instance.
74 */
85export class SpacetimeHostError extends Error {
9- public readonly code : number ;
10- public readonly message : string ;
11- constructor ( code : number , message ?: string ) {
12- super ( ) ;
13- const proto = Object . getPrototypeOf ( this ) ;
14- let cls ;
15- if ( errorProtoypes . has ( proto ) ) {
16- cls = proto . constructor ;
17- if ( code !== cls . CODE )
18- throw new TypeError ( `invalid error code for ${ cls . name } ` ) ;
19- } else if ( proto === SpacetimeHostError . prototype ) {
20- cls = errnoToClass . get ( code ) ;
21- if ( ! cls ) throw new RangeError ( `unknown error code ${ code } ` ) ;
22- } else {
23- throw new TypeError ( 'cannot subclass SpacetimeError' ) ;
24- }
25- Object . setPrototypeOf ( this , cls . prototype ) ;
26- this . code = cls . CODE ;
27- this . message = message ?? cls . MESSAGE ;
6+ constructor ( message : string ) {
7+ super ( message ) ;
288 }
299 get name ( ) : string {
30- return errnoToClass . get ( this . code ) ?. name ?? 'SpacetimeHostError' ;
10+ return 'SpacetimeHostError' ;
3111 }
3212}
3313
@@ -50,110 +30,89 @@ const errorData = {
5030 /**
5131 * A generic error class for unknown error codes.
5232 */
53- HostCallFailure : [ 1 , 'ABI called by host returned an error' ] ,
33+ HostCallFailure : 1 ,
5434
5535 /**
5636 * Error indicating that an ABI call was made outside of a transaction.
5737 */
58- NotInTransaction : [ 2 , 'ABI call can only be made while in a transaction' ] ,
38+ NotInTransaction : 2 ,
5939
6040 /**
6141 * Error indicating that BSATN decoding failed.
6242 * This typically means that the data could not be decoded to the expected type.
6343 */
64- BsatnDecodeError : [ 3 , "Couldn't decode the BSATN to the expected type" ] ,
44+ BsatnDecodeError : 3 ,
6545
6646 /**
6747 * Error indicating that a specified table does not exist.
6848 */
69- NoSuchTable : [ 4 , 'No such table' ] ,
49+ NoSuchTable : 4 ,
7050
7151 /**
7252 * Error indicating that a specified index does not exist.
7353 */
74- NoSuchIndex : [ 5 , 'No such index' ] ,
54+ NoSuchIndex : 5 ,
7555
7656 /**
7757 * Error indicating that a specified row iterator is not valid.
7858 */
79- NoSuchIter : [ 6 , 'The provided row iterator is not valid' ] ,
59+ NoSuchIter : 6 ,
8060
8161 /**
8262 * Error indicating that a specified console timer does not exist.
8363 */
84- NoSuchConsoleTimer : [ 7 , 'The provided console timer does not exist' ] ,
64+ NoSuchConsoleTimer : 7 ,
8565
8666 /**
8767 * Error indicating that a specified bytes source or sink is not valid.
8868 */
89- NoSuchBytes : [ 8 , 'The provided bytes source or sink is not valid' ] ,
69+ NoSuchBytes : 8 ,
9070
9171 /**
9272 * Error indicating that a provided sink has no more space left.
9373 */
94- NoSpace : [ 9 , 'The provided sink has no more space left' ] ,
74+ NoSpace : 9 ,
9575
9676 /**
9777 * Error indicating that there is no more space in the database.
9878 */
99- BufferTooSmall : [
100- 11 ,
101- 'The provided buffer is not large enough to store the data' ,
102- ] ,
79+ BufferTooSmall : 11 ,
10380
10481 /**
10582 * Error indicating that a value with a given unique identifier already exists.
10683 */
107- UniqueAlreadyExists : [
108- 12 ,
109- 'Value with given unique identifier already exists' ,
110- ] ,
84+ UniqueAlreadyExists : 12 ,
11185
11286 /**
11387 * Error indicating that the specified delay in scheduling a row was too long.
11488 */
115- ScheduleAtDelayTooLong : [
116- 13 ,
117- 'Specified delay in scheduling row was too long' ,
118- ] ,
89+ ScheduleAtDelayTooLong : 13 ,
11990
12091 /**
12192 * Error indicating that an index was not unique when it was expected to be.
12293 */
123- IndexNotUnique : [ 14 , 'The index was not unique' ] ,
94+ IndexNotUnique : 14 ,
12495
12596 /**
12697 * Error indicating that an index was not unique when it was expected to be.
12798 */
128- NoSuchRow : [ 15 , 'The row was not found, e.g., in an update call' ] ,
99+ NoSuchRow : 15 ,
129100
130101 /**
131102 * Error indicating that an auto-increment sequence has overflowed.
132103 */
133- AutoIncOverflow : [ 16 , 'The auto-increment sequence overflowed' ] ,
104+ AutoIncOverflow : 16 ,
134105
135- WouldBlockTransaction : [
136- 17 ,
137- 'Attempted async or blocking op while holding open a transaction' ,
138- ] ,
106+ WouldBlockTransaction : 17 ,
139107
140- TransactionNotAnonymous : [
141- 18 ,
142- 'Not in an anonymous transaction. Called by a reducer?' ,
143- ] ,
108+ TransactionNotAnonymous : 18 ,
144109
145- TransactionIsReadOnly : [
146- 19 ,
147- 'ABI call can only be made while within a mutable transaction' ,
148- ] ,
110+ TransactionIsReadOnly : 19 ,
149111
150- TransactionIsMut : [
151- 20 ,
152- 'ABI call can only be made while within a read-only transaction' ,
153- ] ,
112+ TransactionIsMut : 20 ,
154113
155- HttpError : [ 21 , 'The HTTP request failed' ] ,
156- } as const ;
114+ HttpError : 21 ,
115+ } ;
157116
158117function mapEntries < const T extends Record < string , any > , U > (
159118 x : T ,
@@ -164,30 +123,27 @@ function mapEntries<const T extends Record<string, any>, U>(
164123 ) as any ;
165124}
166125
126+ /**
127+ * Map from error codes to their corresponding SpacetimeError subclass.
128+ */
129+ const errnoToClass = new Map < number , new ( msg : string ) => Error > ( ) ;
130+
167131export const errors = Object . freeze (
168- mapEntries ( errorData , ( name , [ code , message ] ) =>
169- Object . defineProperty (
132+ mapEntries ( errorData , ( name , code ) => {
133+ const cls = Object . defineProperty (
170134 class extends SpacetimeHostError {
171- static CODE = code ;
172- static MESSAGE = message ;
173- constructor ( ) {
174- super ( code ) ;
135+ get name ( ) {
136+ return name ;
175137 }
176138 } ,
177139 'name' ,
178140 { value : name , writable : false }
179- )
180- )
141+ ) ;
142+ errnoToClass . set ( code , cls ) ;
143+ return cls ;
144+ } )
181145) ;
182146
183- /**
184- * Set of prototypes of all SpacetimeError subclasses for quick lookup.
185- */
186- const errorProtoypes = new Set ( Object . values ( errors ) . map ( cls => cls . prototype ) ) ;
187-
188- /**
189- * Map from error codes to their corresponding SpacetimeError subclass.
190- */
191- const errnoToClass = new Map (
192- Object . values ( errors ) . map ( cls => [ cls . CODE as number , cls ] )
193- ) ;
147+ export function getErrorConstructor ( code : number ) : new ( msg : string ) => Error {
148+ return errnoToClass . get ( code ) ?? SpacetimeHostError ;
149+ }
0 commit comments