DB operations don't execute when promise is not awaited
The following snippet will not actually execute the SQL update:
My understanding is that this is because the promise is not chained by
then
, catch
, or finally
. This has nothing to do with the DB schema nor with the presence of the void
keyword in front of it.
I understand that this is part of a feature because sometimes you may want to do toSQL
or prepare
, in which case we do not want to execute the operation immediately. However the above situation represents a legit use-case (running a DB operation without blocking the current function), and the result is almost certainly not intended behaviour.
I am aware of work-arounds like chaining an empty .finally(() => {})
or calling .execute()
explicitely, but I thought I'd report this bug anyways because it may affect others.4 Replies
This is intended behavior. As you have stated, drizzle implements a type of lazy promise, that are only executed when awaited.
You have also shared the way it's intended to be used when you need to actually execute the promise
The execute method exists for this reason
Ok, thanks. I think this behaviour is potentially problematic. I'll see if I can write a custom eslint rule to catch this
Let me know what you come up with. We added an eslint plugin to help with this type of stuff. You can consider submitting a PR
Hello again. I am using the
no-restricted-syntax
rule for simplicity, so I wrote the following AST selector:
It's not 100% precise since it can potentially have false-positives, and it also assumes Drizzle is used via a variable called db
, but good enough for my purposes
Leaving this here in case it helps others.
Update: I've fixed the above ES query to the following:
This matches expressions where void
is used on a chain of functions on db
or tx
, which doesn't end with .execute()
. I'm not going to submit a PR for this because there are a lot of edge cases which are not accounted for here, but this version is more precise than the one I posted before.