Skip to content
Clone
80f9e01
53 lines 1.8 KB Rust
use async_graphql::ErrorExtensions;
use crate::share::errors::GitError;
/// Standardized error code extension on every GraphQL error.
fn code_for(err: &GitError) -> &'static str {
match err {
GitError::NotFound => "NOT_FOUND",
GitError::Unauthorized => "UNAUTHORIZED",
GitError::Forbidden => "FORBIDDEN",
GitError::Conflict(_) => "CONFLICT",
GitError::InvalidArgument(_) => "INVALID_ARGUMENT",
GitError::Cache(_) => "CACHE_ERROR",
GitError::Git(_) => "GIT_ERROR",
GitError::Internal(_) => "INTERNAL_ERROR",
}
}
impl ErrorExtensions for GitError {
fn extend(&self) -> async_graphql::Error {
let code = code_for(self);
match self {
GitError::Cache(_) | GitError::Git(_) | GitError::Internal(_) => {
tracing::error!(error = %self, "graphql internal error");
}
_ => {}
}
async_graphql::Error::new(self.to_string()).extend_with(|_, e| {
e.set("code", code);
})
}
}
/// Convert GitError into GraphQL error with `code` extension. Use this
/// directly inside resolvers to keep call sites terse.
pub fn to_gql(err: GitError) -> async_graphql::Error {
err.extend()
}
/// gitbaby (low-level) errors carry no GitError context; surface them as
/// GIT_ERROR-tagged GraphQL errors.
pub fn map_git_baby<E: std::fmt::Display>(err: E) -> async_graphql::Error {
tracing::error!(error = %err, "graphql gitbaby error");
async_graphql::Error::new(err.to_string()).extend_with(|_, e| {
e.set("code", "GIT_ERROR");
})
}
/// Stub for code paths that today must satisfy an internal type-witness
/// (`map_bitbucket_error`) but aren't actually wired to bitbucket.
pub fn map_bitbucket_error(err: GitError) -> GitError {
err
}