Closed venkatd closed 2 years ago
In general, we'd know the operation name if we gracefully handle errors in our multi. In such case, the return from Repo.transaction would be: {:error, operation_name, changeset, operations}
. For uniqueness constraint specifically this would only work when we gracefully handle it with Ecto.Changeset.unique_constraint/3
. If don't gracefully handle errors, if we crash out of our transaction, unfortunately there is no good way to connect the crash to the operation that caused it. Well, there's always the process dictionary escape hatch, we could do this:
multi =
Ecto.Multi.new()
|> Ecto.Multi.run(
:foo,
fn _repo, _changes ->
Process.put(:multi_operation_name, :foo)
raise "oops"
end
)
try do
Repo.transaction(multi)
rescue
e ->
IO.inspect(multi_operation_name: Process.get(:multi_operation_name))
reraise e, __STACKTRACE__
end
But yeah, this is definitely a last resort sort of thing and as anytime we use pdict, it's asking for trouble down the road.
Hi @wojtekmach thanks!
I guess as a compromise we can at least return the entire Ecto.Multi
. I want to make it easier to identify mistakes during development. So if I write a bad query/multi in a particular handler, I can point to the exact line of code+event where the mistake happened.
I'll avoid the process solution if I can, but good to know that this is an option!
Hi @TurtleAI/eds
I'm finding that when
Ecto.Repo.transaction
fails due to something like a constraint error, I'm unable to find the key of the operation that failed.I'd like to show a more helpful message that correlates an event to the Ecto operation that triggered it and getting the key would help here.
I have a
try ... rescue
here: https://github.com/TurtleAI/derive/blob/b430a9a318efe66fc62076ea5ceded7e5f4a9f12/lib/derive/state/ecto.ex#L39And I rescue an error of this form:
Is there a way to get the name of
Ecto.Multi
operation that this error was triggered for? Or if this isn't possible, maybe there's a way to validate these individual operations before executing them?Thanks!