-
Notifications
You must be signed in to change notification settings - Fork 40
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
clean up use of public_error_from_diesel*
#644
Conversation
I like this change - thanks for cleaning it up! - but I still feel bothered by the name What do you think about renaming it to |
I hear you about that. But |
FWIW, I approved this change, because I don't think we need to hold up the PR on my naming nit. Other ideas:
|
Okay, I landed this as-is for now. That's an interesting thought. Both of these provide a sort of default conversion from PoolError to PublicError (whether by an explicit conversion in the language or a name that suggests it's the main way to do that conversion). I kind of think we got into a bit of a mess here because we had one function looks like a catch-all, but really there are 3-4 different modes and you really want to think about which mode you're in rather than copying and pasting or picking a default option. Still, I agree the name here is imprecise and unwieldy. It might also be the abstraction that's a little fuzzy here. If we had different functions for doing these different types of queries, they could do the appropriate error handling for the query. We could ensure other kinds of consistency here, too. For example: If you use Yet another idea:
(I know these names are terrible.) |
Ooooo I kinda like putting the context in an enum. It centralizes the error conversion (no more "looking for the right function") but it makes it easy to pick a low-cost one. I can toy around with implementing this. |
When running database queries in datastore.rs, we use the
public_error_from_diesel*
family of functions fromnexus/src/db/error.rs
to translate database errors into appropriate external API errors. There are a lot of possible cases.Every database query can result in:
If those are the only two errors that can happen, callers can use
public_error_from_diesel_pool_shouldnt_fail()
to handle errors. This function explicitly checks for the 503 case and turns anything else into a 500.Other errors are also possible. These depend on the kind of query we're running. Most queries fall into one of these buckets:
public_error_from_diesel_pool_create
, which takes extra arguments that are used to construct a useful "name already exists" message.public_error_from_diesel_pool
, which takes extra arguments that are used to construct a useful "not found" message.I've left out INSERT, UPDATE, and DELETE statements that may affect 0 or more rows because they're not relevant here.
Today, case 3 (SELECTs that can return 0 or more results and still be valid) tend to use
public_error_from_diesel_pool
with a specialLookupType::Other
argument with the string "Listing All" or something like that. I don't believe this case can ever happen. For us to produce a 404, we need to get backDieselError::NotFound
, which means we've usedfirst_async()
orget_result_async()
when running the query, which is the way we tell Diesel that we expect one result. Naturally, we never do this when we're expecting 0 or more results.This change:
public_error_from_diesel_pool_shouldnt_fail
rather thanpublic_error_from_diesel_pool
. To summarize what I said above: theshouldnt_fail
version is intended for cases where a 500 or 503 can still happen, but 400-level errors can't. On the other hand,public_error_from_diesel_pool
is structured for cases that can return a 404, which these cannot.LookupType::Other
, since it's no longer used. This makes sense: all lookups are either by id or name. With one exception, the only cases whereLookupType::Other
was used were cases that couldn't produce a 404 anyway and so shouldn't need to construct aLookupType
. In the exceptional case, it was easy to make the appropriate 404 directly.public_error_from_diesel_pool
topublic_error_from_diesel_pool_lookup
, which I think better reflects that this function is intended for the specific case where you expect exactly one result.public_error_from_diesel_pool_authz
. Rather than accepting aLookupType
, this accepts anauthz::ApiResource
, which can be used to construct the appropriate 404 error. (Implementors ofApiResource
know their own LookupType already. This function avoids callers having to specify it again.)