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

Flatten error handling, reducing generics #54

Merged
merged 2 commits into from
Oct 6, 2023
Merged

Conversation

smklein
Copy link
Collaborator

@smklein smklein commented Oct 5, 2023

This is a clean-up enabled by #52

  • Removes the ConnErr generic variant
  • Propagates a raw diesel error type, rather than a "connection variant". The old variant was used to encapsulate either "a database error" or "a checkout error". Since callers now must checkout connections before issuing queries, these don't need to be intermingled.

@smklein
Copy link
Collaborator Author

smklein commented Oct 5, 2023

See: oxidecomputer/omicron#4210 for usage

@smklein smklein requested review from jmpesp and sunshowers October 5, 2023 02:35
@sunshowers
Copy link

General question, is returning a DieselError directly correct or do we want to return a newtype on it (or maybe a DieselError with some augmented information?)

Copy link

@sunshowers sunshowers left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good other than the question about whether we want to return our own type for future expandability.

@smklein
Copy link
Collaborator Author

smklein commented Oct 5, 2023

General question, is returning a DieselError directly correct or do we want to return a newtype on it (or maybe a DieselError with some augmented information?)

Can I dig into what you're suggesting here? I don't necessarily disagree, but I want to get a better idea of "costs, pros, and cons".

It wasn't a simple "wrapper" newtype, but this is kinda what the ConnectionError was being used for, basically:

enum ConnectionError {
  Database(DieselError),
  Connection(WeFailedToPollTheConnectionPool),
}

Arguably we could have had additional layers, other errors here, etc... but this was painful from an ergonomics point-of-view, because most of the time when someone issues a request to the DB, error-handling is specific to "what did the DB say", meaning that callers want to match on the Database variant (see: oxidecomputer/omicron#4210 ).

We could add a wrapper type like:

enum AsyncBb8DieselError(DieselError);

But I dunno how advantageous that would be over just returning the type directly, since clients need to match on / decompose that DieselError, so we can't hide the type forever.

@sunshowers
Copy link

sunshowers commented Oct 5, 2023

I do agree that this is a huge improvement over the current situation -- mixing connection and database errors doesn't seem quite right for the reasons you pointed out.

What about:

struct AsyncBb8DieselError {
    error: DieselError,
    // ... some extra fields, e.g. identifier for the connection in the pool}

I'm wondering if issues like #47 would have been ever so slightly easier to spot with that extra info.

But I certainly won't block on this.

@smklein
Copy link
Collaborator Author

smklein commented Oct 5, 2023

I do agree that this is a huge improvement over the current situation -- mixing connection and database errors doesn't seem quite right for the reasons you pointed out.

What about:

struct AsyncBb8DieselError {
    error: DieselError,
    // ... some extra fields, e.g. identifier for the connection in the pool}

I'm wondering if issues like #47 would have been ever so slightly easier to spot with that extra info.

But I certainly won't block on this.

Ah, that makes sense. If we were sticking with async-bb8-diesel forever, I'd be strongly in favor of this direction.

I will throw out one more caveat -- this whole crate pre-dated diesel-async, and was kinda a stop-gap (see: oxidecomputer/omicron#4188 ). That crate directly returns DieselErrors, so aligning with it would make conversion easier. Similarly, breaking that convention makes conversion slightly harder.

With this in mind, I think I'm going to move forward on this PR as-is, but I really do like the proposal of "struct as a wrapper around an underlying error + easy access to underlying error, but extra auxiliary error info which can be propagated back up" too.

@smklein smklein merged commit 1446f7e into master Oct 6, 2023
3 checks passed
@smklein smklein deleted the error-handling branch October 6, 2023 19:28
smklein added a commit to oxidecomputer/omicron that referenced this pull request Oct 12, 2023
Depends on oxidecomputer/async-bb8-diesel#54

As of #4140 , we check out
connections before issuing queries to the underlying database. This
means that when we receive errors from the database, they are not
overloaded as "connection checkout" OR "database" errors - they are now
always database errors.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants