Skip to content

Datastore has its own error type #357

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

Closed
wants to merge 3 commits into from
Closed

Datastore has its own error type #357

wants to merge 3 commits into from

Conversation

david-crespo
Copy link
Contributor

@david-crespo david-crespo commented Nov 2, 2021

Getting a start on prototyping #347. Generally I think all the datastore functions should return a datastore error, and then it's the responsibility of the nexus wrapper (probably, could also be the endpoint) to convert it to an external error. UpdateResult is trivial to convert because there's only one query in all three examples, so I started with that.

The insight that I'm rolling with here is that if public_error_from_diesel_pool is what we call with errors everywhere, then roughly speaking the datastore error struct just needs to represent the args to public_error_from_diesel_pool:

pub struct DSError {
    error: PoolError,
    resource_type: ResourceType,
    lookup_type: LookupType,
}

And then we can make public_error_from_diesel_pool the From that converts a DSError to an external error.

impl From<DSError> for Error {
    fn from(e: DSError) -> Self {
        public_error_from_diesel_pool(e.error, e.resource_type, e.lookup_type)
    }
}

Unfortunately it's not quite that simple, because there's also public_error_from_diesel_pool_create for create errors, which would be ok, but there are methods that might return both kinds of error, for example project create: it gives a normal error if it can't find the org, but a create error if it can't create the project.

.map_err(|e| match e {
InsertError::CollectionNotFound => Error::ObjectNotFound {
type_name: ResourceType::Organization,
lookup_type: LookupType::ById(organization_id),
},
InsertError::DatabaseError(e) => {
public_error_from_diesel_pool_create(
e,
ResourceType::Project,
&name,
)
}
})

So if there's a single common datastore Error type, it probably has to be an enum of both create and non-create error info.

@david-crespo david-crespo marked this pull request as draft November 3, 2021 15:50
@davepacheco
Copy link
Collaborator

I think authorization errors will show up too. You can have the equivalents of both Error::Unauthenticated and Error::Forbidden. We also currently return InternalError from Datastore in some cases.

@david-crespo david-crespo force-pushed the db-errors branch 2 times, most recently from f51a485 to 2288092 Compare November 8, 2021 17:37
Invariant {
message: String,
},
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

different kinds of errors have different metadata, so this becomes a whole thing

pub type LookupResult<T> = Result<T, Error>;
/** Result of an update operation for the specified type */
pub type UpdateResult<T> = Result<T, DSError>;

Copy link
Contributor Author

Choose a reason for hiding this comment

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

these don't all have to have the same kind of error — instead of the big pattern match on the error type in Error::from, there could be CreateError etc and they each have their own Error::from

@david-crespo
Copy link
Contributor Author

I will come back to this later.

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