Skip to content

Commit

Permalink
simplify QueryError
Browse files Browse the repository at this point in the history
  • Loading branch information
mmkal committed Sep 13, 2024
1 parent 41d3c22 commit 9396d7c
Show file tree
Hide file tree
Showing 10 changed files with 166 additions and 181 deletions.
99 changes: 50 additions & 49 deletions apps/docs/pages/packages/client.md
Original file line number Diff line number Diff line change
Expand Up @@ -531,7 +531,8 @@ client = createClient(client.connectionString(), {
} catch (e) {
if (e instanceof QueryError && e.message.endsWith('Parsing rows failed')) {
throw new QueryError(e.message, {
cause: {query: e.cause.query, error: fromError(e.cause.error)},
query: e.cause.query,
error: fromError(e.cause.error),
})
}
throw e
Expand Down Expand Up @@ -1177,55 +1178,55 @@ For errors based on the number of rows returned (for `one`, `oneFirst`, `many`,
```typescript
await expect(pool.one(sql`select * from test_errors where id > 1`)).rejects.toMatchInlineSnapshot(
`
[[Query select-test_errors_36f5f64]: Expected one row]
{
"message": "[Query select-test_errors_36f5f64]: Expected one row",
"cause": {
"query": {
"name": "select-test_errors_36f5f64",
"sql": "select * from test_errors where id > 1",
"token": "sql",
"values": []
},
"result": {
"rows": [
{
"id": 2,
"name": "two"
},
{
"id": 3,
"name": "three"
}
],
"command": "SELECT",
"rowCount": 2,
"fields": [
{
"name": "id",
"tableID": 123456789,
"columnID": 1,
"dataTypeID": 123456789,
"dataTypeSize": 4,
"dataTypeModifier": -1,
"format": "text"
},
{
"name": "name",
"tableID": 123456789,
"columnID": 2,
"dataTypeID": 123456789,
"dataTypeSize": -1,
"dataTypeModifier": -1,
"format": "text"
}
]
},
"message": "",
"name": "QueryErrorCause"
[[Query select-test_errors_36f5f64]: Expected one row]
{
"message": "[Query select-test_errors_36f5f64]: Expected one row",
"cause": {
"query": {
"name": "select-test_errors_36f5f64",
"sql": "select * from test_errors where id > 1",
"token": "sql",
"values": []
},
"result": {
"rows": [
{
"id": 2,
"name": "two"
},
{
"id": 3,
"name": "three"
}
],
"command": "SELECT",
"rowCount": 2,
"fields": [
{
"name": "id",
"tableID": 123456789,
"columnID": 1,
"dataTypeID": 123456789,
"dataTypeSize": 4,
"dataTypeModifier": -1,
"format": "text"
},
{
"name": "name",
"tableID": 123456789,
"columnID": 2,
"dataTypeID": 123456789,
"dataTypeSize": -1,
"dataTypeModifier": -1,
"format": "text"
}
]
},
"message": "",
"name": "QueryErrorCause"
}
}
}
`,
`,
)
```

Expand Down
99 changes: 50 additions & 49 deletions packages/client/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -532,7 +532,8 @@ client = createClient(client.connectionString(), {
} catch (e) {
if (e instanceof QueryError && e.message.endsWith('Parsing rows failed')) {
throw new QueryError(e.message, {
cause: {query: e.cause.query, error: fromError(e.cause.error)},
query: e.cause.query,
error: fromError(e.cause.error),
})
}
throw e
Expand Down Expand Up @@ -1178,55 +1179,55 @@ For errors based on the number of rows returned (for `one`, `oneFirst`, `many`,
```typescript
await expect(pool.one(sql`select * from test_errors where id > 1`)).rejects.toMatchInlineSnapshot(
`
[[Query select-test_errors_36f5f64]: Expected one row]
{
"message": "[Query select-test_errors_36f5f64]: Expected one row",
"cause": {
"query": {
"name": "select-test_errors_36f5f64",
"sql": "select * from test_errors where id > 1",
"token": "sql",
"values": []
},
"result": {
"rows": [
{
"id": 2,
"name": "two"
},
{
"id": 3,
"name": "three"
}
],
"command": "SELECT",
"rowCount": 2,
"fields": [
{
"name": "id",
"tableID": 123456789,
"columnID": 1,
"dataTypeID": 123456789,
"dataTypeSize": 4,
"dataTypeModifier": -1,
"format": "text"
},
{
"name": "name",
"tableID": 123456789,
"columnID": 2,
"dataTypeID": 123456789,
"dataTypeSize": -1,
"dataTypeModifier": -1,
"format": "text"
}
]
},
"message": "",
"name": "QueryErrorCause"
[[Query select-test_errors_36f5f64]: Expected one row]
{
"message": "[Query select-test_errors_36f5f64]: Expected one row",
"cause": {
"query": {
"name": "select-test_errors_36f5f64",
"sql": "select * from test_errors where id > 1",
"token": "sql",
"values": []
},
"result": {
"rows": [
{
"id": 2,
"name": "two"
},
{
"id": 3,
"name": "three"
}
],
"command": "SELECT",
"rowCount": 2,
"fields": [
{
"name": "id",
"tableID": 123456789,
"columnID": 1,
"dataTypeID": 123456789,
"dataTypeSize": 4,
"dataTypeModifier": -1,
"format": "text"
},
{
"name": "name",
"tableID": 123456789,
"columnID": 2,
"dataTypeID": 123456789,
"dataTypeSize": -1,
"dataTypeModifier": -1,
"format": "text"
}
]
},
"message": "",
"name": "QueryErrorCause"
}
}
}
`,
`,
)
```

Expand Down
32 changes: 8 additions & 24 deletions packages/client/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,12 @@ const createQueryable = (query: Queryable['query']): Queryable => {
query,
async one(input) {
const result = await query(input)
if (result.rows.length !== 1) throw new QueryError('Expected one row', {cause: {query: input, result}})
if (result.rows.length !== 1) throw new QueryError('Expected one row', {query: input, result})
return result.rows[0]
},
async maybeOne(input) {
const result = await query(input)
if (result.rows.length > 1)
throw new QueryError('Expected at most one row', {
cause: {query: input, result},
})
if (result.rows.length > 1) throw new QueryError('Expected at most one row', {query: input, result})
return result.rows[0] ?? null
},
async any(input) {
Expand All @@ -49,31 +46,22 @@ const createQueryable = (query: Queryable['query']): Queryable => {
},
async many(input) {
const result = await query(input)
if (result.rows.length === 0)
throw new QueryError('Expected at least one row', {
cause: {query: input, result},
})
if (result.rows.length === 0) throw new QueryError('Expected at least one row', {query: input, result})
return result.rows
},
async manyFirst(input) {
const result = await query(input)
if (result.rows.length === 0)
throw new QueryError('Expected at least one row', {
cause: {query: input, result},
})
if (result.rows.length === 0) throw new QueryError('Expected at least one row', {query: input, result})
return result.rows.map(first)
},
async maybeOneFirst(input) {
const result = await query(input)
if (result.rows.length > 1)
throw new QueryError('Expected at most one row', {
cause: {query: input, result},
})
if (result.rows.length > 1) throw new QueryError('Expected at most one row', {query: input, result})
return result.rows.length === 1 ? first(result.rows[0]) : null
},
async oneFirst(input) {
const result = await query(input)
if (result.rows.length !== 1) throw new QueryError('Expected one row', {cause: {query: input, result}})
if (result.rows.length !== 1) throw new QueryError('Expected one row', {query: input, result})
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-return, @typescript-eslint/no-explicit-any
return Object.values(result.rows[0] as any)[0] as any
},
Expand All @@ -94,18 +82,14 @@ export const createQueryFn = (pgpQueryable: pgPromise.ITask<any> | pgPromise.IDa
result = {rows, command, rowCount, fields}
} catch (err: unknown) {
const error = errorFromUnknown(err)
throw new QueryError(error.message, {
cause: {query, error},
})
throw new QueryError(error.message, {query, error})
}

try {
return {...result, rows: await Promise.all(result.rows.map(query.parse))}
} catch (err: unknown) {
const error = errorFromUnknown(err)
throw new QueryError(`Parsing rows failed`, {
cause: {query, error},
})
throw new QueryError(`Parsing rows failed`, {query, error})
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion packages/client/src/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export class QueryError extends Error {
result?: {rows: unknown[]}
}

constructor(message: string, {cause}: {cause: Omit<QueryError['cause'], 'name' | 'message'>}) {
constructor(message: string, cause: Omit<QueryError['cause'], 'name' | 'message'>) {
super(`[Query ${cause.query.name}]: ${message || cause?.error?.message || cause?.error?.constructor?.name}`, {
cause,
})
Expand Down
4 changes: 1 addition & 3 deletions packages/client/src/sql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,9 +164,7 @@ const sqlFn: SQLTagFunction = (strings, ...inputParameters) => {
const unexpected = param satisfies never as (typeof inputParameters)[number]
throw new QueryError(
`Unknown type ${unexpected && typeof unexpected === 'object' ? unexpected.token : typeof unexpected}`,
{
cause: {query: {name: nameQuery(strings), sql, values: inputParameters}},
},
{query: {name: nameQuery(strings), sql, values: inputParameters}},
)
}
}
Expand Down
3 changes: 2 additions & 1 deletion packages/client/test/api-usage.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,8 @@ test('sql.type with custom error message', async () => {
} catch (e) {
if (e instanceof QueryError && e.message.endsWith('Parsing rows failed')) {
throw new QueryError(e.message, {
cause: {query: e.cause.query, error: fromError(e.cause.error)},
query: e.cause.query,
error: fromError(e.cause.error),
})
}
throw e
Expand Down
Loading

0 comments on commit 9396d7c

Please sign in to comment.