edgedb-js
edgedb-js copied to clipboard
Add user code context to errors for easier debugging of failed queries
I just got this error in prod
err: {
"type": "CardinalityViolationError",
"message": "assert_exists violation: expression returned an empty set\n",
"stack":
CardinalityViolationError: assert_exists violation: expression returned an empty set
at RawConnection._parseErrorMessage (/opt/render/project/src/node_modules/edgedb/dist/baseConn.js:329:21)
at RawConnection._executeFlow (/opt/render/project/src/node_modules/edgedb/dist/baseConn.js:936:34)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async RawConnection.fetch (/opt/render/project/src/node_modules/edgedb/dist/baseConn.js:988:17)
at async Transaction._runOp (/opt/render/project/src/node_modules/edgedb/dist/transaction.js:99:20)
at async ClientConnectionHolder.transaction (/opt/render/project/src/node_modules/edgedb/dist/baseClient.js:139:26)
at async Client.transaction (/opt/render/project/src/node_modules/edgedb/dist/baseClient.js:473:20)
at async Object.<anonymous> (/opt/render/project/src/dist/src/app.js:139:17)
}
only problem is I have quite a lot of assert_exists scattered throughout my codebase, and this error gives me very little to help me narrow down which of them is the one that failed.
It would be really helpful if one of the lines in the stack included the location of my actual line of query code that caused the error, or even just printed the query that triggered the failure.
Instead it only shows the outermost line where the failure happened (in this case app.js:139:17), which requires me to:
- try to build my code so it is identical to what is deployed in prod (not always trivial, due to potentially different versions of npm, TS, and other node_modules libraries between dev and prod)
- look at the relevant line in my compiled JS to try and find which edgeql query is made at that location
- try to figure out which line of that query is actually the one failing
We recently did a round of improvements to the error messaging (https://github.com/edgedb/edgedb-js/pull/731). Which version of edgedb are you on?
I'm on Cloud v4.0
EDIT: unless you meant the npm deps, in which case they are "edgedb": "^1.4.0" and "@edgedb/generate": "^0.4.0"
When the server returns information on where the error occurred, you should get an error with some context like this:
QueryError: function "assert_exists()" does not exist
|
1 | select assert_exists()
| ^^^^^^^^^^^^^^^
Hint: Did you want "std::assert_exists(input: SET OF anytype, NAMED ONLY message: OPTIONAL std::str=<str>{})"?
But in this case, I think the server is just not returning that information:
await client.query(`select assert_exists(<str>{})`);
// Just throws this:
// CardinalityViolationError: assert_exists violation: expression returned an empty set
@scotttrinh I guess when the server doesn't return a location we could put the whole query in the error message? Though I'm not sure if that would be too noisy in error logs, especially if the queries are large. Maybe we should implement more customisable logging like this: https://github.com/edgedb/edgedb-js/issues/318?