Reputation: 31143
I am currently debugging some tests written with jest over typescript and I'm having a bit of a headache.
If a test, or tested class, runs Postgres SQL and there is an error in the query, I get the wrong stack trace, for example, this:
error: invalid input syntax for type integer: ""0""
at Parser.parseErrorMessage (/Users/sklivvz/src/xxx/node_modules/pg-protocol/src/parser.ts:369:69)
at Parser.handlePacket (/Users/sklivvz/src/xxx/node_modules/pg-protocol/src/parser.ts:188:21)
at Parser.parse (/Users/sklivvz/src/xxx/node_modules/pg-protocol/src/parser.ts:103:30)
at Socket.<anonymous> (/Users/sklivvz/src/xxx/node_modules/pg-protocol/src/index.ts:7:48)
at Socket.emit (node:events:365:28)
at addChunk (node:internal/streams/readable:314:12)
at readableAddChunk (node:internal/streams/readable:289:9)
at Socket.Readable.push (node:internal/streams/readable:228:10)
at TCP.onStreamRead (node:internal/stream_base_commons:190:23)
The "error" line is very useful, however, the stack trace only tells me that the error was thrown by the pg-protocol driver. I would like to know which line within my code generated the error.
I am exactly 82.7% sure that this is due to PG's query
being async.
It is incredibly time-consuming having to step debug or (gasp) console.log
my way to each error when it would only be a matter of showing the correct call stack in order to make it better.
Has anyone found a way of making this developer-friendly?
Upvotes: 6
Views: 2492
Reputation: 1645
I ran into a similar issue with aws-sdk for DynamoDb. This is a stacktrace I usually get from aws-sdk.
ResourceNotFoundException: Requested resource not found
at Request.extractError (D:\workspaces\typescript-starters\console-app\node_modules\aws-sdk\lib\protocol\json.js:52:27)
at Request.callListeners (D:\workspaces\typescript-starters\console-app\node_modules\aws-sdk\lib\sequential_executor.js:106:20)
at Request.emit (D:\workspaces\typescript-starters\console-app\node_modules\aws-sdk\lib\sequential_executor.js:78:10)
at Request.emit (D:\workspaces\typescript-starters\console-app\node_modules\aws-sdk\lib\request.js:688:14)
at Request.transition (D:\workspaces\typescript-starters\console-app\node_modules\aws-sdk\lib\request.js:22:10)
at AcceptorStateMachine.runTo (D:\workspaces\typescript-starters\console-app\node_modules\aws-sdk\lib\state_machine.js:14:12)
at D:\workspaces\typescript-starters\console-app\node_modules\aws-sdk\lib\state_machine.js:26:10
at Request.<anonymous> (D:\workspaces\typescript-starters\console-app\node_modules\aws-sdk\lib\request.js:38:9)
at Request.<anonymous> (D:\workspaces\typescript-starters\console-app\node_modules\aws-sdk\lib\request.js:690:12)
at Request.callListeners (D:\workspaces\typescript-starters\console-app\node_modules\aws-sdk\lib\sequential_executor.js:116:18)
My workaround is simply to catch async errors, and overwrite their stack traces. On the other hand, you may append Postgres stacktrace, or error message to your own errors.
async function getPersonFromDb (personId: string): Promise<DocumentClient.AttributeMap | undefined> {
const result = await documentClient.get({ // Similar to postgres.query()
TableName: 'wrong-name',
Key: { pk: personId, sk: personId }
}).promise().catch(error => {
Error.captureStackTrace(error)
throw error
})
return result.Item
}
test('Get a person from DynamoDB', async () => {
const person = await getPersonFromDb('hello')
expect(person).not.toBeUndefined()
})
// ========= new stacktrace ========
Error: Requested resource not found
at D:\workspaces\typescript-starters\console-app\test\abc.test.ts:12:13
at processTicksAndRejections (internal/process/task_queues.js:93:5)
at getPersonFromDb (D:\workspaces\typescript-starters\console-app\test\abc.test.ts:8:20)
at Object.<anonymous> (D:\workspaces\typescript-starters\console-app\test\abc.test.ts:18:20) // my code, and where my error is thrown
Upvotes: 1
Reputation: 1326524
Check if this is related to brianc/node-postgres
issue 2484
is (there) a preferred package, extension, or method for providing more detail when you get a syntax error back from the parser?
(for instance, one that listed line number, column of the error)for instance, right now:
error: syntax error at or near "as" at Parser.parseErrorMessage (/home/collspec/projects/staff-portal/sprint-server/node_modules/pg-protocol/dist/parser.js:278:15)
desired behavior:
error: syntax error at or near "as", line 5, column 7 at Parser.parseErrorMessage (/home/collspec/projects/staff-portal/sprint-server/node_modules/pg-protocol/dist/parser.js:278:15)
Possible workaround from that issue:
There are a bunch of additional fields on Error objects populated by the driver.
If you log the error object you can see them. They correspond to the error fields returned by the server:For example with the command:
SELECT foo FROM bar
You can get an error like this:
{ length: 102, severity: 'ERROR', code: '42P01', detail: undefined, hint: undefined, position: '17', internalPosition: undefined, internalQuery: undefined, where: undefined, schema: undefined, table: undefined, column: undefined, dataType: undefined, constraint: undefined, file: 'parse_relation.c', line: '1180', routine: 'parserOpenTable' }
The one you want is position. It gives you the character offset in the SQL of the error.
In this example the position value of "17" refers to the start of the bar token in the SQL.
It's not always populated though as it depends on what caused the error (generally just parse errors).
Upvotes: 2