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(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 }