Skip to content

Commit d6a0137

Browse files
committed
fix: use code for OperationError
1 parent 768d4be commit d6a0137

File tree

3 files changed

+23
-68
lines changed

3 files changed

+23
-68
lines changed

README.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -432,9 +432,8 @@ Data provides multiple different error classes to help you differentiate and han
432432

433433
### `OperationError`
434434

435-
- `operationName` `<string>`, the name of the errored operation (e.g. "create", "updateMany", etc.);
436-
- `info` `<object>`, additional operation information (often the operation arguments);
437-
- `cause` `<Error>`, a reference to the original thrown error.
435+
- `code` `<OperationErrorCode>`, the error code describing the failed operation;
436+
- `cause` `<Error>` (_optional_), a reference to the original thrown error.
438437

439438
Thrown whenever performing a record operation fails. For example:
440439

src/collection.ts

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import {
1919
} from '#/src/utils.js'
2020
import { type SortOptions, sortResults } from '#/src/sort.js'
2121
import type { Extension } from '#/src/extensions/index.js'
22-
import { OperationError, StrictOperationError } from '#/src/errors.js'
22+
import { OperationError, OperationErrorCodes } from '#/src/errors.js'
2323
import { TypedEvent, type Emitter } from 'rettime'
2424

2525
let collectionsCreated = 0
@@ -131,16 +131,16 @@ export class Collection<Schema extends StandardSchemaV1> {
131131

132132
if (validationResult.issues) {
133133
console.error(validationResult.issues)
134-
throw new InvariantError(
135-
'Failed to create a new record with initial values (%j): does not match the schema',
136-
initialValues,
134+
throw new OperationError(
135+
'Failed to create a new record with initial values (%j): does not match the schema. Please see the schema validation errors above.',
136+
OperationErrorCodes.INVALID_INITIAL_VALUES,
137137
)
138138
}
139139

140140
let record = validationResult.value as RecordType
141141

142142
invariant.as(
143-
OperationError.for('create', { initialValues }),
143+
OperationError.for(OperationErrorCodes.INVALID_INITIAL_VALUES),
144144
typeof record === 'object',
145145
'Failed to create a record with initial values (%j): expected the record to be an object or an array',
146146
initialValues,
@@ -207,8 +207,7 @@ export class Collection<Schema extends StandardSchemaV1> {
207207
return await Promise.all(pendingPromises).catch((error) => {
208208
throw new OperationError(
209209
'Failed to execute "createMany" on collection: unexpected error',
210-
'createMany',
211-
{ count, initialValuesFactory },
210+
OperationErrorCodes.UNEXPECTED_ERROR,
212211
error,
213212
)
214213
})
@@ -232,7 +231,7 @@ export class Collection<Schema extends StandardSchemaV1> {
232231
const firstRecord = this.#records[0]
233232

234233
invariant.as(
235-
StrictOperationError.for('findFirst', { predicate, options }),
234+
OperationError.for(OperationErrorCodes.STRICT_QUERY_WITHOUT_RESULTS),
236235
options?.strict ? firstRecord != null : true,
237236
'Failed to execute "findFirst" on collection without a query: the collection is empty',
238237
)
@@ -245,7 +244,7 @@ export class Collection<Schema extends StandardSchemaV1> {
245244
).next().value
246245

247246
invariant.as(
248-
StrictOperationError.for('findFirst', { predicate, options }),
247+
OperationError.for(OperationErrorCodes.STRICT_QUERY_WITHOUT_RESULTS),
249248
options?.strict ? result != null : true,
250249
'Failed to execute "findFirst" on collection: no record found matching the query',
251250
)
@@ -277,7 +276,7 @@ export class Collection<Schema extends StandardSchemaV1> {
277276
)
278277

279278
invariant.as(
280-
StrictOperationError.for('findMany', { predicate, options }),
279+
OperationError.for(OperationErrorCodes.STRICT_QUERY_WITHOUT_RESULTS),
281280
options?.strict ? results.length > 0 : true,
282281
'Failed to execute "findMany" on collection: no records found matching the query',
283282
)
@@ -324,7 +323,7 @@ export class Collection<Schema extends StandardSchemaV1> {
324323

325324
if (prevRecord == null) {
326325
invariant.as(
327-
StrictOperationError.for('update', { predicate, options }),
326+
OperationError.for(OperationErrorCodes.STRICT_QUERY_WITHOUT_RESULTS),
328327
!options.strict,
329328
'Failed to execute "update" on collection: no record found matching the query',
330329
)
@@ -363,7 +362,7 @@ export class Collection<Schema extends StandardSchemaV1> {
363362

364363
if (prevRecords.length === 0) {
365364
invariant.as(
366-
StrictOperationError.for('updateMany', { predicate, options }),
365+
OperationError.for(OperationErrorCodes.STRICT_QUERY_WITHOUT_RESULTS),
367366
!options.strict,
368367
'Failed to execute "updateMany" on collection: no records found matching the query',
369368
)
@@ -409,7 +408,7 @@ export class Collection<Schema extends StandardSchemaV1> {
409408

410409
if (record == null) {
411410
invariant.as(
412-
StrictOperationError.for('delete', { predicate, options }),
411+
OperationError.for(OperationErrorCodes.STRICT_QUERY_WITHOUT_RESULTS),
413412
!options?.strict,
414413
'Failed to execute "delete" on collection: no record found matching the query',
415414
)
@@ -445,7 +444,7 @@ export class Collection<Schema extends StandardSchemaV1> {
445444

446445
if (records.length === 0) {
447446
invariant.as(
448-
StrictOperationError.for('deleteMany', { predicate, options }),
447+
OperationError.for(OperationErrorCodes.STRICT_QUERY_WITHOUT_RESULTS),
449448
!options?.strict,
450449
'Failed to execute "deleteMany" on collection: no records found matching the query',
451450
)

src/errors.ts

Lines changed: 8 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,72 +1,29 @@
1-
import { InvariantError } from 'outvariant'
21
import type { Collection } from '#/src/collection.js'
32
import type { PropertyPath } from '#/src/utils.js'
43
import type { RelationDeclarationOptions } from '#/src/relation.js'
54

6-
export interface OperationErrorMap {
7-
create: {
8-
initialValues: Parameters<InstanceType<typeof Collection>['create']>[0]
9-
}
10-
createMany: {
11-
count: number
12-
initialValuesFactory: Parameters<
13-
InstanceType<typeof Collection>['createMany']
14-
>[1]
15-
}
16-
findFirst: {
17-
predicate: Parameters<InstanceType<typeof Collection>['findFirst']>[0]
18-
options: Parameters<InstanceType<typeof Collection>['findFirst']>[1]
19-
}
20-
findMany: {
21-
predicate: Parameters<InstanceType<typeof Collection>['findMany']>[0]
22-
options: Parameters<InstanceType<typeof Collection>['findMany']>[1]
23-
}
24-
update: {
25-
predicate: Parameters<InstanceType<typeof Collection>['update']>[0]
26-
options: Parameters<InstanceType<typeof Collection>['update']>[1]
27-
}
28-
updateMany: {
29-
predicate: Parameters<InstanceType<typeof Collection>['updateMany']>[0]
30-
options: Parameters<InstanceType<typeof Collection>['updateMany']>[1]
31-
}
32-
delete: {
33-
predicate: Parameters<InstanceType<typeof Collection>['delete']>[0]
34-
options: Parameters<InstanceType<typeof Collection>['delete']>[1]
35-
}
36-
deleteMany: {
37-
predicate: Parameters<InstanceType<typeof Collection>['deleteMany']>[0]
38-
options: Parameters<InstanceType<typeof Collection>['deleteMany']>[1]
39-
}
5+
export enum OperationErrorCodes {
6+
UNEXPECTED_ERROR = 'UNEXPECTED_ERROR',
7+
INVALID_INITIAL_VALUES = 'INVALID_INITIAL_VALUES',
8+
STRICT_QUERY_WITHOUT_RESULTS = 'STRICT_QUERY_WITHOUT_RESULTS',
409
}
4110

42-
export class OperationError<
43-
OperationName extends keyof OperationErrorMap,
44-
> extends InvariantError {
45-
static for<OperationName extends keyof OperationErrorMap>(
46-
operationName: OperationName,
47-
info: OperationErrorMap[OperationName],
48-
) {
11+
export class OperationError extends Error {
12+
static for(code: OperationErrorCodes) {
4913
return (message: string) => {
50-
return new OperationError(message, operationName, info)
14+
return new OperationError(message, code)
5115
}
5216
}
5317

5418
constructor(
5519
message: string,
56-
public readonly operationName: OperationName,
57-
public readonly info: OperationErrorMap[OperationName],
20+
public readonly code: OperationErrorCodes,
5821
public readonly cause?: unknown,
5922
) {
6023
super(message)
6124
}
6225
}
6326

64-
export class StrictOperationError<
65-
OperationName extends keyof OperationErrorMap,
66-
> extends OperationError<OperationName> {
67-
static for = OperationError.for
68-
}
69-
7027
export enum RelationErrorCodes {
7128
RELATION_NOT_READY = 'RELATION_NOT_READY',
7229
UNEXPECTED_SET_EXPRESSION = 'UNEXPECTED_SET_EXPRESSION',

0 commit comments

Comments
 (0)