mirror of
https://github.com/kjuulh/dagger-rs.git
synced 2025-07-25 19:09:22 +02:00
Add thiserror instead of exposing eyre anonymous errors
The change here is to make it easier for the consumer to debug the api. Such that they can `match` on individual errors instead of having to parse text. eyre is convenient, but mostly from a consumers perspective
This commit is contained in:
@@ -16,6 +16,7 @@ serde_json = { workspace = true }
|
||||
tokio = { workspace = true }
|
||||
tracing = { workspace = true }
|
||||
tracing-subscriber = { workspace = true }
|
||||
thiserror.workspace = true
|
||||
|
||||
base64 = "0.21.0"
|
||||
dirs = "4.0.0"
|
||||
|
@@ -15,7 +15,7 @@ pub struct GraphQLError {
|
||||
#[derive(Deserialize, Debug, Clone)]
|
||||
#[allow(dead_code)]
|
||||
pub struct GraphQLErrorMessage {
|
||||
message: String,
|
||||
pub message: String,
|
||||
locations: Option<Vec<GraphQLErrorLocation>>,
|
||||
extensions: Option<HashMap<String, String>>,
|
||||
path: Option<Vec<GraphQLErrorPathParam>>,
|
||||
|
@@ -4,13 +4,14 @@ use std::sync::Arc;
|
||||
use async_trait::async_trait;
|
||||
use base64::engine::general_purpose;
|
||||
use base64::Engine;
|
||||
use thiserror::Error;
|
||||
|
||||
use crate::connect_params::ConnectParams;
|
||||
use crate::gql_client::{ClientConfig, GQLClient};
|
||||
|
||||
#[async_trait]
|
||||
pub trait GraphQLClient {
|
||||
async fn query(&self, query: &str) -> eyre::Result<Option<serde_json::Value>>;
|
||||
async fn query(&self, query: &str) -> Result<Option<serde_json::Value>, GraphQLError>;
|
||||
}
|
||||
|
||||
pub type DynGraphQLClient = Arc<dyn GraphQLClient + Send + Sync>;
|
||||
@@ -40,13 +41,50 @@ impl DefaultGraphQLClient {
|
||||
|
||||
#[async_trait]
|
||||
impl GraphQLClient for DefaultGraphQLClient {
|
||||
async fn query(&self, query: &str) -> eyre::Result<Option<serde_json::Value>> {
|
||||
let res: Option<serde_json::Value> = self
|
||||
.client
|
||||
.query(&query)
|
||||
.await
|
||||
.map_err(|r| eyre::anyhow!(r.to_string()))?;
|
||||
async fn query(&self, query: &str) -> Result<Option<serde_json::Value>, GraphQLError> {
|
||||
let res: Option<serde_json::Value> =
|
||||
self.client.query(&query).await.map_err(map_graphql_error)?;
|
||||
|
||||
return Ok(res);
|
||||
}
|
||||
}
|
||||
|
||||
fn map_graphql_error(gql_error: crate::gql_client::GraphQLError) -> GraphQLError {
|
||||
let message = gql_error.message().to_string();
|
||||
let json = gql_error.json();
|
||||
|
||||
if let Some(json) = json {
|
||||
if !json.is_empty() {
|
||||
return GraphQLError::DomainError {
|
||||
message,
|
||||
fields: GraphqlErrorMessages(json.into_iter().map(|e| e.message).collect()),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
GraphQLError::HttpError(message)
|
||||
}
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum GraphQLError {
|
||||
#[error("http error: {0}")]
|
||||
HttpError(String),
|
||||
#[error("domain error:\n{message}\n{fields}")]
|
||||
DomainError {
|
||||
message: String,
|
||||
fields: GraphqlErrorMessages,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct GraphqlErrorMessages(Vec<String>);
|
||||
|
||||
impl std::fmt::Display for GraphqlErrorMessages {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
for error in self.0.iter() {
|
||||
f.write_fmt(format_args!("{error}\n"))?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user