Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollback is not called if there is a panic #637

Closed
4 of 6 tasks
mitar opened this issue Nov 16, 2021 · 2 comments · Fixed by #638
Closed
4 of 6 tasks

Rollback is not called if there is a panic #637

mitar opened this issue Nov 16, 2021 · 2 comments · Fixed by #638
Labels
bug Something is not working.

Comments

@mitar
Copy link
Contributor

mitar commented Nov 16, 2021

Preflight checklist

Describe the bug

Current use of BeginTx, CommitTx and RollbackTx in Fosite is problematic because it does not call RollbackTx when panic happens. We could assume that Fosite itself does not panic, but that is not necessary true for code it calls into. For example, I had a bug inside my storage implementation which triggered panic. As the panic propagated and was handled higher up in my request handler and logged, transaction itself was not rolled back, leaving the connection over it in an inconsistent state. With connection pooling that brought some stability issues.

Reproducing the bug

Sadly I do not have a simple reproduction here. One which I was able to do is with Sqlite and setting SetMaxOpenConns to 1. Then if a transaction is not rolled back, no other operation can be done on the database and my code hangs. This is how I am now testing that all transactions are properly rolled back.

Relevant log output

No response

Relevant configuration

No response

Version

observed on current master branch

On which operating system are you observing this issue?

No response

In which environment are you deploying?

No response

Additional Context

No response

@mitar mitar added the bug Something is not working. label Nov 16, 2021
@aeneasr
Copy link
Member

aeneasr commented Nov 19, 2021

This is also the case for os.Exit, *.Fatal* and other exit scenarios such as unhandled SIGHUP. Most of these we can't detect. IMO catching panics isn't solvable without a substantial transaction refactor. Keep in mind that fosite has transactions optionally available, some storage engines don't even support transactions! The question is if that's worth the effort, as panics are rare and retries are cheap ("oh the server crashed, guess I need to try and refresh the token again").

@mitar
Copy link
Contributor Author

mitar commented Nov 22, 2021

I do not think perfect (catching all possible ways code can exist) should be the enemy of good: catching a standard way for Go code to throw an exception when there is a bug in the code it is calling into, and cleaning up. In fact, Go gives you a nice way to cleanup. I would even say that it would simplify existing code.

See here. There is so many storage.MaybeRollbackTx cases in there. All that could be moved into one defer and this is it.

I can try to do a MR if it would be an acceptable change.

mitar added a commit to mitar/fosite that referenced this issue Nov 24, 2021
@mitar mitar mentioned this issue Nov 24, 2021
6 tasks
mitar added a commit to mitar/fosite that referenced this issue Jan 14, 2022
mitar added a commit to mitar/fosite that referenced this issue Jan 14, 2022
aeneasr added a commit that referenced this issue Feb 23, 2022
Fixes #637

Co-authored-by: hackerman <3372410+aeneasr@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something is not working.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants