The most stable thing to do is to take control of the error handling. If the result of a part of your query can return null, then it would be advisable to handle that inside the query itself in a way that fits your application.
I have not seen a truly canonical way to do this bubble up to the surface yet. There are a couple of things I could suggest though.
abort with a message you app can interpret
Like throwing an error in your app.
let index = 'foo';
let val = 'abc123'
try {
result = await client.query(
q.Let(
{
ref: q.Match(q.Index(index), val),
},
q.If(
q.Exists(q.Var('ref')),
q.Get(q.Var('ref')),
q.Abort('error message')
)
);
} catch (err) {
console.error(err);
}
always return a result
This would be my preferred way to do things “nicely”.
If you’re into functional programming, think Result Monad. But I mean as simple as
const goodResult = {
// optional type value,
// not strictly necessary if you can otherwise distinguish good from bad results
type: 'fooResult',
data: ...
}
const badResult = {
type: 'Error'
message: ...
code: ...
}
You can apply this to the query:
let index = 'foo';
let val = 'abc123'
try {
result = await client.query(
q.Let(
{
ref: q.Match(q.Index(index), val),
},
q.If(
q.Exists(q.Var('ref')),
{
type: 'fooResult',
data: q.Get(q.Var('ref'))
},
{
type: 'Error',
message: 'item not found in index foo',
code: 42
}
)
);
// handle bad results here, not in catch block.
} catch (err) {
// Now only have to handle errors
console.error(err);
}