From b1e1141da091e6354ba1cdd02518c7df049aeef5 Mon Sep 17 00:00:00 2001 From: Mehul Mathur Date: Thu, 15 Aug 2024 13:46:50 +0000 Subject: [PATCH 1/5] refactor: move cli error to core --- src/cli/mod.rs | 2 - src/cli/runtime/file.rs | 6 +- src/cli/server/http_1.rs | 6 +- src/cli/server/http_2.rs | 4 +- src/cli/server/http_server.rs | 4 +- src/cli/tc/check.rs | 4 +- src/cli/telemetry.rs | 6 +- src/{cli/error.rs => core/errata.rs} | 107 +++++++++++++++------------ src/core/mod.rs | 3 + src/main.rs | 6 +- 10 files changed, 80 insertions(+), 68 deletions(-) rename src/{cli/error.rs => core/errata.rs} (77%) diff --git a/src/cli/mod.rs b/src/cli/mod.rs index 59798bc6b5..eebb64373a 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -1,5 +1,4 @@ pub mod command; -mod error; mod fmt; pub mod generator; #[cfg(feature = "js")] @@ -11,5 +10,4 @@ pub mod server; mod tc; pub mod telemetry; pub(crate) mod update_checker; -pub use error::CLIError; pub use tc::run::run; diff --git a/src/cli/runtime/file.rs b/src/cli/runtime/file.rs index 3d9be7ed77..e644bf18ad 100644 --- a/src/cli/runtime/file.rs +++ b/src/cli/runtime/file.rs @@ -1,6 +1,6 @@ use tokio::io::{AsyncReadExt, AsyncWriteExt}; -use crate::cli::CLIError; +use crate::core::Errata; use crate::core::FileIO; #[derive(Clone)] @@ -29,7 +29,7 @@ async fn write<'a>(path: &'a str, content: &'a [u8]) -> anyhow::Result<()> { impl FileIO for NativeFileIO { async fn write<'a>(&'a self, path: &'a str, content: &'a [u8]) -> anyhow::Result<()> { write(path, content).await.map_err(|err| { - CLIError::new(format!("Failed to write file: {}", path).as_str()) + Errata::new(format!("Failed to write file: {}", path).as_str()) .description(err.to_string()) })?; tracing::info!("File write: {} ... ok", path); @@ -38,7 +38,7 @@ impl FileIO for NativeFileIO { async fn read<'a>(&'a self, path: &'a str) -> anyhow::Result { let content = read(path).await.map_err(|err| { - CLIError::new(format!("Failed to read file: {}", path).as_str()) + Errata::new(format!("Failed to read file: {}", path).as_str()) .description(err.to_string()) })?; tracing::info!("File read: {} ... ok", path); diff --git a/src/cli/server/http_1.rs b/src/cli/server/http_1.rs index 22d7d97c96..3e8e065f47 100644 --- a/src/cli/server/http_1.rs +++ b/src/cli/server/http_1.rs @@ -4,7 +4,7 @@ use hyper::service::{make_service_fn, service_fn}; use tokio::sync::oneshot; use super::server_config::ServerConfig; -use crate::cli::CLIError; +use crate::core::Errata; use crate::core::async_graphql_hyper::{GraphQLBatchRequest, GraphQLRequest}; use crate::core::http::handle_request; @@ -31,7 +31,7 @@ pub async fn start_http_1( } }); let builder = hyper::Server::try_bind(&addr) - .map_err(CLIError::from)? + .map_err(Errata::from)? .http1_pipeline_flush(sc.app_ctx.blueprint.server.pipeline_flush); super::log_launch(sc.as_ref()); @@ -48,7 +48,7 @@ pub async fn start_http_1( builder.serve(make_svc_single_req).await }; - let result = server.map_err(CLIError::from); + let result = server.map_err(Errata::from); Ok(result?) } diff --git a/src/cli/server/http_2.rs b/src/cli/server/http_2.rs index 30ee21b5d1..47a0183f0f 100644 --- a/src/cli/server/http_2.rs +++ b/src/cli/server/http_2.rs @@ -9,7 +9,7 @@ use rustls_pki_types::{CertificateDer, PrivateKeyDer}; use tokio::sync::oneshot; use super::server_config::ServerConfig; -use crate::cli::CLIError; +use crate::core::Errata; use crate::core::async_graphql_hyper::{GraphQLBatchRequest, GraphQLRequest}; use crate::core::http::handle_request; @@ -60,7 +60,7 @@ pub async fn start_http_2( builder.serve(make_svc_single_req).await }; - let result = server.map_err(CLIError::from); + let result = server.map_err(Errata::from); Ok(result?) } diff --git a/src/cli/server/http_server.rs b/src/cli/server/http_server.rs index 62928c492f..22de2e9e1a 100644 --- a/src/cli/server/http_server.rs +++ b/src/cli/server/http_server.rs @@ -8,7 +8,7 @@ use super::http_1::start_http_1; use super::http_2::start_http_2; use super::server_config::ServerConfig; use crate::cli::telemetry::init_opentelemetry; -use crate::cli::CLIError; +use crate::core::Errata; use crate::core::blueprint::{Blueprint, Http}; use crate::core::config::ConfigModule; @@ -32,7 +32,7 @@ impl Server { /// Starts the server in the current Runtime pub async fn start(self) -> Result<()> { - let blueprint = Blueprint::try_from(&self.config_module).map_err(CLIError::from)?; + let blueprint = Blueprint::try_from(&self.config_module).map_err(Errata::from)?; let endpoints = self.config_module.extensions().endpoint_set.clone(); let server_config = Arc::new(ServerConfig::new(blueprint.clone(), endpoints).await?); diff --git a/src/cli/tc/check.rs b/src/cli/tc/check.rs index 9e41cb7a9d..ee2338d3e4 100644 --- a/src/cli/tc/check.rs +++ b/src/cli/tc/check.rs @@ -2,7 +2,7 @@ use anyhow::Result; use super::helpers::{display_schema, log_endpoint_set}; use crate::cli::fmt::Fmt; -use crate::cli::CLIError; +use crate::core::Errata; use crate::core::blueprint::Blueprint; use crate::core::config::reader::ConfigReader; use crate::core::config::Source; @@ -24,7 +24,7 @@ pub(super) async fn check_command(params: CheckParams, config_reader: &ConfigRea if let Some(format) = format { Fmt::display(format.encode(&config_module)?); } - let blueprint = Blueprint::try_from(&config_module).map_err(CLIError::from); + let blueprint = Blueprint::try_from(&config_module).map_err(Errata::from); match blueprint { Ok(blueprint) => { diff --git a/src/cli/telemetry.rs b/src/cli/telemetry.rs index 3b315b2ab7..e3df6e88b5 100644 --- a/src/cli/telemetry.rs +++ b/src/cli/telemetry.rs @@ -24,7 +24,7 @@ use tracing_subscriber::layer::SubscriberExt; use tracing_subscriber::{Layer, Registry}; use super::metrics::init_metrics; -use crate::cli::CLIError; +use crate::core::Errata; use crate::core::blueprint::telemetry::{OtlpExporter, Telemetry, TelemetryExporter}; use crate::core::runtime::TargetRuntime; use crate::core::tracing::{default_tracing_tailcall, get_log_level, tailcall_filter_target}; @@ -204,8 +204,8 @@ pub fn init_opentelemetry(config: Telemetry, runtime: &TargetRuntime) -> anyhow: | global::Error::Log(LogError::Other(_)), ) { tracing::subscriber::with_default(default_tracing_tailcall(), || { - let cli = crate::cli::CLIError::new("Open Telemetry Error") - .caused_by(vec![CLIError::new(error.to_string().as_str())]) + let cli = crate::core::Errata::new("Open Telemetry Error") + .caused_by(vec![Errata::new(error.to_string().as_str())]) .trace(vec!["schema".to_string(), "@telemetry".to_string()]); tracing::error!("{}", cli.color(true)); }); diff --git a/src/cli/error.rs b/src/core/errata.rs similarity index 77% rename from src/cli/error.rs rename to src/core/errata.rs index 50e06e5301..4c875b1f57 100644 --- a/src/cli/error.rs +++ b/src/core/errata.rs @@ -2,12 +2,15 @@ use std::fmt::{Debug, Display}; use colored::Colorize; use derive_setters::Setters; -use thiserror::Error; +use crate::core::error::Error as CoreError; use crate::core::valid::ValidationError; -#[derive(Debug, Error, Setters, PartialEq, Clone)] -pub struct CLIError { +/// The moral equivalent of a serde_json::Value but for errors. +/// It's a data structure like Value that can hold any error in an untyped +/// manner. +#[derive(Debug, thiserror::Error, Setters, PartialEq, Clone)] +pub struct Errata { is_root: bool, #[setters(skip)] color: bool, @@ -17,12 +20,12 @@ pub struct CLIError { trace: Vec, #[setters(skip)] - caused_by: Vec, + caused_by: Vec, } -impl CLIError { +impl Errata { pub fn new(message: &str) -> Self { - CLIError { + Errata { is_root: true, color: false, message: message.to_string(), @@ -32,7 +35,7 @@ impl CLIError { } } - pub fn caused_by(mut self, error: Vec) -> Self { + pub fn caused_by(mut self, error: Vec) -> Self { self.caused_by = error; for error in self.caused_by.iter_mut() { @@ -82,7 +85,7 @@ fn bullet(str: &str) -> String { chars.into_iter().collect::() } -impl Display for CLIError { +impl Display for Errata { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let default_padding = 2; @@ -132,46 +135,46 @@ impl Display for CLIError { } } -impl From for CLIError { +impl From for Errata { fn from(error: hyper::Error) -> Self { - // TODO: add type-safety to CLIError conversion - let cli_error = CLIError::new("Server Failed"); + // TODO: add type-safety to Errata conversion + let cli_error = Errata::new("Server Failed"); let message = error.to_string(); if message.to_lowercase().contains("os error 48") { cli_error .description("The port is already in use".to_string()) - .caused_by(vec![CLIError::new(message.as_str())]) + .caused_by(vec![Errata::new(message.as_str())]) } else { cli_error.description(message) } } } -impl From for CLIError { +impl From for Errata { fn from(error: rustls::Error) -> Self { - let cli_error = CLIError::new("Failed to create TLS Acceptor"); + let cli_error = Errata::new("Failed to create TLS Acceptor"); let message = error.to_string(); cli_error.description(message) } } -impl From for CLIError { +impl From for Errata { fn from(error: anyhow::Error) -> Self { - // Convert other errors to CLIError - let cli_error = match error.downcast::() { + // Convert other errors to Errata + let cli_error = match error.downcast::() { Ok(cli_error) => cli_error, Err(error) => { - // Convert other errors to CLIError + // Convert other errors to Errata let cli_error = match error.downcast::>() { - Ok(validation_error) => CLIError::from(validation_error), + Ok(validation_error) => Errata::from(validation_error), Err(error) => { let sources = error .source() - .map(|error| vec![CLIError::new(error.to_string().as_str())]) + .map(|error| vec![Errata::new(error.to_string().as_str())]) .unwrap_or_default(); - CLIError::new(&error.to_string()).caused_by(sources) + Errata::new(&error.to_string()).caused_by(sources) } }; cli_error @@ -181,24 +184,33 @@ impl From for CLIError { } } -impl From for CLIError { +impl From for Errata { fn from(error: std::io::Error) -> Self { - let cli_error = CLIError::new("IO Error"); + let cli_error = Errata::new("IO Error"); let message = error.to_string(); cli_error.description(message) } } -impl<'a> From> for CLIError { +impl From for Errata { + fn from(error: CoreError) -> Self { + let cli_error = Errata::new("Core Error"); + let message = error.to_string(); + + cli_error.description(message) + } +} + +impl<'a> From> for Errata { fn from(error: ValidationError<&'a str>) -> Self { - CLIError::new("Invalid Configuration").caused_by( + Errata::new("Invalid Configuration").caused_by( error .as_vec() .iter() .map(|cause| { let mut err = - CLIError::new(cause.message).trace(Vec::from(cause.trace.clone())); + Errata::new(cause.message).trace(Vec::from(cause.trace.clone())); if let Some(description) = cause.description { err = err.description(description.to_owned()); } @@ -209,29 +221,28 @@ impl<'a> From> for CLIError { } } -impl From> for CLIError { +impl From> for Errata { fn from(error: ValidationError) -> Self { - CLIError::new("Invalid Configuration").caused_by( + Errata::new("Invalid Configuration").caused_by( error .as_vec() .iter() .map(|cause| { - CLIError::new(cause.message.as_str()).trace(Vec::from(cause.trace.clone())) + Errata::new(cause.message.as_str()).trace(Vec::from(cause.trace.clone())) }) .collect(), ) } } -impl From> for CLIError { +impl From> for Errata { fn from(value: Box) -> Self { - CLIError::new(value.to_string().as_str()) + Errata::new(value.to_string().as_str()) } } #[cfg(test)] mod tests { - use pretty_assertions::assert_eq; use stripmargin::StripMargin; @@ -275,14 +286,14 @@ mod tests { #[test] fn test_title() { - let error = CLIError::new("Server could not be started"); + let error = Errata::new("Server could not be started"); let expected = r"Server could not be started".strip_margin(); assert_eq!(error.to_string(), expected); } #[test] fn test_title_description() { - let error = CLIError::new("Server could not be started") + let error = Errata::new("Server could not be started") .description("The port is already in use".to_string()); let expected = r"|Server could not be started: The port is already in use".strip_margin(); @@ -291,7 +302,7 @@ mod tests { #[test] fn test_title_description_trace() { - let error = CLIError::new("Server could not be started") + let error = Errata::new("Server could not be started") .description("The port is already in use".to_string()) .trace(vec!["@server".into(), "port".into()]); @@ -304,7 +315,7 @@ mod tests { #[test] fn test_title_trace_caused_by() { - let error = CLIError::new("Configuration Error").caused_by(vec![CLIError::new( + let error = Errata::new("Configuration Error").caused_by(vec![Errata::new( "Base URL needs to be specified", ) .trace(vec![ @@ -324,20 +335,20 @@ mod tests { #[test] fn test_title_trace_multiple_caused_by() { - let error = CLIError::new("Configuration Error").caused_by(vec![ - CLIError::new("Base URL needs to be specified").trace(vec![ + let error = Errata::new("Configuration Error").caused_by(vec![ + Errata::new("Base URL needs to be specified").trace(vec![ "User".into(), "posts".into(), "@http".into(), "baseURL".into(), ]), - CLIError::new("Base URL needs to be specified").trace(vec![ + Errata::new("Base URL needs to be specified").trace(vec![ "Post".into(), "users".into(), "@http".into(), "baseURL".into(), ]), - CLIError::new("Base URL needs to be specified") + Errata::new("Base URL needs to be specified") .description("Set `baseURL` in @http or @server directives".into()) .trace(vec![ "Query".into(), @@ -345,7 +356,7 @@ mod tests { "@http".into(), "baseURL".into(), ]), - CLIError::new("Base URL needs to be specified").trace(vec![ + Errata::new("Base URL needs to be specified").trace(vec![ "Query".into(), "posts".into(), "@http".into(), @@ -370,7 +381,7 @@ mod tests { .description("Set `baseURL` in @http or @server directives") .trace(vec!["Query", "users", "@http", "baseURL"]); let valid = ValidationError::from(cause); - let error = CLIError::from(valid); + let error = Errata::from(valid); let expected = r"|Invalid Configuration |Caused by: | • Base URL needs to be specified: Set `baseURL` in @http or @server directives [at Query.users.@http.baseURL]" @@ -381,12 +392,12 @@ mod tests { #[test] fn test_cli_error_identity() { - let cli_error = CLIError::new("Server could not be started") + let cli_error = Errata::new("Server could not be started") .description("The port is already in use".to_string()) .trace(vec!["@server".into(), "port".into()]); let anyhow_error: anyhow::Error = cli_error.clone().into(); - let actual = CLIError::from(anyhow_error); + let actual = Errata::from(anyhow_error); let expected = cli_error; assert_eq!(actual, expected); @@ -399,8 +410,8 @@ mod tests { ); let anyhow_error: anyhow::Error = validation_error.clone().into(); - let actual = CLIError::from(anyhow_error); - let expected = CLIError::from(validation_error); + let actual = Errata::from(anyhow_error); + let expected = Errata::from(validation_error); assert_eq!(actual, expected); } @@ -409,8 +420,8 @@ mod tests { fn test_generic_error() { let anyhow_error = anyhow::anyhow!("Some error msg"); - let actual: CLIError = CLIError::from(anyhow_error); - let expected = CLIError::new("Some error msg"); + let actual: Errata = Errata::from(anyhow_error); + let expected = Errata::new("Some error msg"); assert_eq!(actual, expected); } diff --git a/src/core/mod.rs b/src/core/mod.rs index 5ca24f55e9..25857dd73e 100644 --- a/src/core/mod.rs +++ b/src/core/mod.rs @@ -40,6 +40,9 @@ mod transform; pub mod try_fold; pub mod valid; pub mod worker; +mod errata; + +pub use errata::Errata; // Re-export everything from `tailcall_macros` as `macros` use std::borrow::Cow; diff --git a/src/main.rs b/src/main.rs index 3e912d28ad..4f75ffe521 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,7 +3,7 @@ use std::cell::Cell; -use tailcall::cli::CLIError; +use tailcall::core::Errata; use tailcall::core::tracing::default_tracing_tailcall; use tracing::subscriber::DefaultGuard; @@ -42,8 +42,8 @@ fn main() -> anyhow::Result<()> { match result { Ok(_) => {} Err(error) => { - // Ensure all errors are converted to CLIErrors before being printed. - let cli_error: CLIError = error.into(); + // Ensure all errors are converted to Errata before being printed. + let cli_error: Errata = error.into(); tracing::error!("{}", cli_error.color(true)); std::process::exit(exitcode::CONFIG); } From 2a599cf7ca712b7e2b7227210e1d2ded6f65d51d Mon Sep 17 00:00:00 2001 From: Mehul Mathur Date: Thu, 15 Aug 2024 14:18:10 +0000 Subject: [PATCH 2/5] chore: use Errata in IR --- src/core/grpc/request.rs | 2 +- src/core/http/response.rs | 4 +-- src/core/ir/error.rs | 68 +++++++++++++++++++++++++++------------ src/core/ir/eval.rs | 4 +-- src/core/ir/eval_http.rs | 2 +- 5 files changed, 54 insertions(+), 26 deletions(-) diff --git a/src/core/grpc/request.rs b/src/core/grpc/request.rs index c7e28b53e3..7bea4ccd68 100644 --- a/src/core/grpc/request.rs +++ b/src/core/grpc/request.rs @@ -160,7 +160,7 @@ mod tests { if let Err(err) = result { match err.downcast_ref::() { - Some(Error::GRPCError { + Some(Error::GRPC { grpc_code, grpc_description, grpc_status_message, diff --git a/src/core/http/response.rs b/src/core/http/response.rs index 2bb28e2b93..4300e8035e 100644 --- a/src/core/http/response.rs +++ b/src/core/http/response.rs @@ -103,7 +103,7 @@ impl Response { let grpc_status = match Status::from_header_map(&self.headers) { Some(status) => status, None => { - return Error::IOException("Error while parsing upstream headers".to_owned()).into() + return Error::IO("Error while parsing upstream headers".to_owned()).into() } }; @@ -136,7 +136,7 @@ impl Response { } obj.insert(Name::new("details"), ConstValue::List(status_details)); - let error = Error::GRPCError { + let error = Error::GRPC { grpc_code: grpc_status.code() as i32, grpc_description: grpc_status.code().description().to_owned(), grpc_status_message: grpc_status.message().to_owned(), diff --git a/src/core/ir/error.rs b/src/core/ir/error.rs index e08523bb71..5ebc74ed64 100644 --- a/src/core/ir/error.rs +++ b/src/core/ir/error.rs @@ -1,48 +1,76 @@ +use std::fmt::Display; use std::sync::Arc; use async_graphql::{ErrorExtensions, Value as ConstValue}; use derive_more::From; use thiserror::Error; +use crate::core::Errata; use crate::core::{auth, cache, worker}; #[derive(From, Debug, Error, Clone)] pub enum Error { - #[error("IOException: {0}")] - IOException(String), + IO(String), - #[error("gRPC Error: status: {grpc_code}, description: `{grpc_description}`, message: `{grpc_status_message}`")] - GRPCError { + GRPC { grpc_code: i32, grpc_description: String, grpc_status_message: String, grpc_status_details: ConstValue, }, - #[error("APIValidationError: {0:?}")] - APIValidationError(Vec), + APIValidation(Vec), - #[error("ExprEvalError: {0}")] #[from(ignore)] - ExprEvalError(String), + ExprEval(String), - #[error("DeserializeError: {0}")] #[from(ignore)] - DeserializeError(String), + Deserialize(String), - #[error("Authentication Failure: {0}")] - AuthError(auth::error::Error), + Auth(auth::error::Error), - #[error("Worker Error: {0}")] - WorkerError(worker::Error), + Worker(worker::Error), - #[error("Cache Error: {0}")] - CacheError(cache::Error), + Cache(cache::Error), +} + +impl Display for Error { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + Errata::from(self.to_owned()).fmt(f) + } +} + +impl From for Errata { + fn from(value: Error) -> Self { + match value { + Error::IO(message) => Errata::new("IOException").description(message), + Error::GRPC { + grpc_code, + grpc_description, + grpc_status_message, + grpc_status_details: _, + } => Errata::new("GRPC Error") + .description(format!("status: {grpc_code}, description: `{grpc_description}`, message: `{grpc_status_message}")), + Error::APIValidation(errors) => Errata::new("API Validation Error") + .caused_by(errors.iter().map(|e| Errata::new(e)).collect::>()), + Error::Deserialize(message) => { + Errata::new("Deserialization Error").description(message) + } + Error::ExprEval(message) => { + Errata::new("Expression Evaluation Error").description(message) + } + Error::Auth(err) => { + Errata::new("Authentication Failure").description(err.to_string()) + } + Error::Worker(err) => Errata::new("Worker Error").description(err.to_string()), + Error::Cache(err) => Errata::new("Cache Error").description(err.to_string()), + } + } } impl ErrorExtensions for Error { fn extend(&self) -> async_graphql::Error { async_graphql::Error::new(format!("{}", self)).extend_with(|_err, e| { - if let Error::GRPCError { + if let Error::GRPC { grpc_code, grpc_description, grpc_status_message, @@ -60,7 +88,7 @@ impl ErrorExtensions for Error { impl<'a> From> for Error { fn from(value: crate::core::valid::ValidationError<&'a str>) -> Self { - Error::APIValidationError( + Error::APIValidation( value .as_vec() .iter() @@ -74,7 +102,7 @@ impl From> for Error { fn from(error: Arc) -> Self { match error.downcast_ref::() { Some(err) => err.clone(), - None => Error::IOException(error.to_string()), + None => Error::IO(error.to_string()), } } } @@ -86,7 +114,7 @@ impl From for Error { fn from(value: anyhow::Error) -> Self { match value.downcast::() { Ok(err) => err, - Err(err) => Error::IOException(err.to_string()), + Err(err) => Error::IO(err.to_string()), } } } diff --git a/src/core/ir/eval.rs b/src/core/ir/eval.rs index 595cb57dbd..aabee086cb 100644 --- a/src/core/ir/eval.rs +++ b/src/core/ir/eval.rs @@ -72,13 +72,13 @@ impl IR { if let Some(value) = map.get(&key) { Ok(ConstValue::String(value.to_owned())) } else { - Err(Error::ExprEvalError(format!( + Err(Error::ExprEval(format!( "Can't find mapped key: {}.", key ))) } } else { - Err(Error::ExprEvalError( + Err(Error::ExprEval( "Mapped key must be string value.".to_owned(), )) } diff --git a/src/core/ir/eval_http.rs b/src/core/ir/eval_http.rs index bc99ef72a9..446eb9009a 100644 --- a/src/core/ir/eval_http.rs +++ b/src/core/ir/eval_http.rs @@ -236,7 +236,7 @@ pub fn parse_graphql_response( field_name: &str, ) -> Result { let res: async_graphql::Response = - from_value(res.body).map_err(|err| Error::DeserializeError(err.to_string()))?; + from_value(res.body).map_err(|err| Error::Deserialize(err.to_string()))?; for error in res.errors { ctx.add_error(error); From a56aac91f0bfed49bff681493d9c1772cb712138 Mon Sep 17 00:00:00 2001 From: Mehul Mathur Date: Thu, 15 Aug 2024 14:32:48 +0000 Subject: [PATCH 3/5] test: updated snapshots --- tests/core/snapshots/grpc-error.md_0.snap | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/snapshots/grpc-error.md_0.snap b/tests/core/snapshots/grpc-error.md_0.snap index cca7ca0d8c..3a0d22331d 100644 --- a/tests/core/snapshots/grpc-error.md_0.snap +++ b/tests/core/snapshots/grpc-error.md_0.snap @@ -11,7 +11,7 @@ expression: response "data": null, "errors": [ { - "message": "gRPC Error: status: 3, description: `Client specified an invalid argument`, message: `grpc message`", + "message": "GRPC Error: status: 3, description: `Client specified an invalid argument`, message: `grpc message", "locations": [ { "line": 1, From 6f57d8d1042eb3f121ae7c799a74beb3858db2d3 Mon Sep 17 00:00:00 2001 From: Mehul Mathur Date: Thu, 15 Aug 2024 14:44:13 +0000 Subject: [PATCH 4/5] fix: lint --- src/cli/runtime/file.rs | 3 +-- src/cli/server/http_1.rs | 2 +- src/cli/server/http_2.rs | 2 +- src/cli/server/http_server.rs | 2 +- src/cli/tc/check.rs | 2 +- src/cli/telemetry.rs | 2 +- src/core/errata.rs | 3 +-- src/core/http/response.rs | 4 +--- src/core/ir/error.rs | 7 +++---- src/core/ir/eval.rs | 5 +---- src/core/mod.rs | 5 ++--- src/main.rs | 2 +- tests/core/snapshots/grpc-error.md_0.snap | 2 +- 13 files changed, 16 insertions(+), 25 deletions(-) diff --git a/src/cli/runtime/file.rs b/src/cli/runtime/file.rs index e644bf18ad..72a55160c6 100644 --- a/src/cli/runtime/file.rs +++ b/src/cli/runtime/file.rs @@ -1,7 +1,6 @@ use tokio::io::{AsyncReadExt, AsyncWriteExt}; -use crate::core::Errata; -use crate::core::FileIO; +use crate::core::{Errata, FileIO}; #[derive(Clone)] pub struct NativeFileIO {} diff --git a/src/cli/server/http_1.rs b/src/cli/server/http_1.rs index 3e8e065f47..76360e860a 100644 --- a/src/cli/server/http_1.rs +++ b/src/cli/server/http_1.rs @@ -4,9 +4,9 @@ use hyper::service::{make_service_fn, service_fn}; use tokio::sync::oneshot; use super::server_config::ServerConfig; -use crate::core::Errata; use crate::core::async_graphql_hyper::{GraphQLBatchRequest, GraphQLRequest}; use crate::core::http::handle_request; +use crate::core::Errata; pub async fn start_http_1( sc: Arc, diff --git a/src/cli/server/http_2.rs b/src/cli/server/http_2.rs index 47a0183f0f..1895789603 100644 --- a/src/cli/server/http_2.rs +++ b/src/cli/server/http_2.rs @@ -9,9 +9,9 @@ use rustls_pki_types::{CertificateDer, PrivateKeyDer}; use tokio::sync::oneshot; use super::server_config::ServerConfig; -use crate::core::Errata; use crate::core::async_graphql_hyper::{GraphQLBatchRequest, GraphQLRequest}; use crate::core::http::handle_request; +use crate::core::Errata; pub async fn start_http_2( sc: Arc, diff --git a/src/cli/server/http_server.rs b/src/cli/server/http_server.rs index 22de2e9e1a..3661c9f5f7 100644 --- a/src/cli/server/http_server.rs +++ b/src/cli/server/http_server.rs @@ -8,9 +8,9 @@ use super::http_1::start_http_1; use super::http_2::start_http_2; use super::server_config::ServerConfig; use crate::cli::telemetry::init_opentelemetry; -use crate::core::Errata; use crate::core::blueprint::{Blueprint, Http}; use crate::core::config::ConfigModule; +use crate::core::Errata; pub struct Server { config_module: ConfigModule, diff --git a/src/cli/tc/check.rs b/src/cli/tc/check.rs index ee2338d3e4..6816836092 100644 --- a/src/cli/tc/check.rs +++ b/src/cli/tc/check.rs @@ -2,11 +2,11 @@ use anyhow::Result; use super::helpers::{display_schema, log_endpoint_set}; use crate::cli::fmt::Fmt; -use crate::core::Errata; use crate::core::blueprint::Blueprint; use crate::core::config::reader::ConfigReader; use crate::core::config::Source; use crate::core::runtime::TargetRuntime; +use crate::core::Errata; pub(super) struct CheckParams { pub(super) file_paths: Vec, diff --git a/src/cli/telemetry.rs b/src/cli/telemetry.rs index e3df6e88b5..22643e73fb 100644 --- a/src/cli/telemetry.rs +++ b/src/cli/telemetry.rs @@ -24,10 +24,10 @@ use tracing_subscriber::layer::SubscriberExt; use tracing_subscriber::{Layer, Registry}; use super::metrics::init_metrics; -use crate::core::Errata; use crate::core::blueprint::telemetry::{OtlpExporter, Telemetry, TelemetryExporter}; use crate::core::runtime::TargetRuntime; use crate::core::tracing::{default_tracing_tailcall, get_log_level, tailcall_filter_target}; +use crate::core::Errata; static RESOURCE: Lazy = Lazy::new(|| { Resource::default().merge(&Resource::new(vec![ diff --git a/src/core/errata.rs b/src/core/errata.rs index 4c875b1f57..e10ba0d5cd 100644 --- a/src/core/errata.rs +++ b/src/core/errata.rs @@ -209,8 +209,7 @@ impl<'a> From> for Errata { .as_vec() .iter() .map(|cause| { - let mut err = - Errata::new(cause.message).trace(Vec::from(cause.trace.clone())); + let mut err = Errata::new(cause.message).trace(Vec::from(cause.trace.clone())); if let Some(description) = cause.description { err = err.description(description.to_owned()); } diff --git a/src/core/http/response.rs b/src/core/http/response.rs index 4300e8035e..710ab0ac1a 100644 --- a/src/core/http/response.rs +++ b/src/core/http/response.rs @@ -102,9 +102,7 @@ impl Response { pub fn to_grpc_error(&self, operation: &ProtobufOperation) -> anyhow::Error { let grpc_status = match Status::from_header_map(&self.headers) { Some(status) => status, - None => { - return Error::IO("Error while parsing upstream headers".to_owned()).into() - } + None => return Error::IO("Error while parsing upstream headers".to_owned()).into(), }; let mut obj: IndexMap = IndexMap::new(); diff --git a/src/core/ir/error.rs b/src/core/ir/error.rs index 5ebc74ed64..2bcd513f83 100644 --- a/src/core/ir/error.rs +++ b/src/core/ir/error.rs @@ -4,9 +4,8 @@ use std::sync::Arc; use async_graphql::{ErrorExtensions, Value as ConstValue}; use derive_more::From; use thiserror::Error; -use crate::core::Errata; -use crate::core::{auth, cache, worker}; +use crate::core::{auth, cache, worker, Errata}; #[derive(From, Debug, Error, Clone)] pub enum Error { IO(String), @@ -48,8 +47,8 @@ impl From for Errata { grpc_description, grpc_status_message, grpc_status_details: _, - } => Errata::new("GRPC Error") - .description(format!("status: {grpc_code}, description: `{grpc_description}`, message: `{grpc_status_message}")), + } => Errata::new("gRPC Error") + .description(format!("status: {grpc_code}, description: `{grpc_description}`, message: `{grpc_status_message}`")), Error::APIValidation(errors) => Errata::new("API Validation Error") .caused_by(errors.iter().map(|e| Errata::new(e)).collect::>()), Error::Deserialize(message) => { diff --git a/src/core/ir/eval.rs b/src/core/ir/eval.rs index aabee086cb..89cded1663 100644 --- a/src/core/ir/eval.rs +++ b/src/core/ir/eval.rs @@ -72,10 +72,7 @@ impl IR { if let Some(value) = map.get(&key) { Ok(ConstValue::String(value.to_owned())) } else { - Err(Error::ExprEval(format!( - "Can't find mapped key: {}.", - key - ))) + Err(Error::ExprEval(format!("Can't find mapped key: {}.", key))) } } else { Err(Error::ExprEval( diff --git a/src/core/mod.rs b/src/core/mod.rs index 25857dd73e..a885e5ab4f 100644 --- a/src/core/mod.rs +++ b/src/core/mod.rs @@ -12,6 +12,7 @@ pub mod data_loader; pub mod directive; pub mod document; pub mod endpoint; +mod errata; pub mod error; pub mod generator; pub mod graphql; @@ -40,9 +41,6 @@ mod transform; pub mod try_fold; pub mod valid; pub mod worker; -mod errata; - -pub use errata::Errata; // Re-export everything from `tailcall_macros` as `macros` use std::borrow::Cow; @@ -50,6 +48,7 @@ use std::hash::Hash; use std::num::NonZeroU64; use async_graphql_value::ConstValue; +pub use errata::Errata; pub use error::{Error, Result}; use http::Response; use ir::model::IoId; diff --git a/src/main.rs b/src/main.rs index 4f75ffe521..b2dc98e001 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,8 +3,8 @@ use std::cell::Cell; -use tailcall::core::Errata; use tailcall::core::tracing::default_tracing_tailcall; +use tailcall::core::Errata; use tracing::subscriber::DefaultGuard; thread_local! { diff --git a/tests/core/snapshots/grpc-error.md_0.snap b/tests/core/snapshots/grpc-error.md_0.snap index 3a0d22331d..cca7ca0d8c 100644 --- a/tests/core/snapshots/grpc-error.md_0.snap +++ b/tests/core/snapshots/grpc-error.md_0.snap @@ -11,7 +11,7 @@ expression: response "data": null, "errors": [ { - "message": "GRPC Error: status: 3, description: `Client specified an invalid argument`, message: `grpc message", + "message": "gRPC Error: status: 3, description: `Client specified an invalid argument`, message: `grpc message`", "locations": [ { "line": 1, From 0de3131395c9e5b23bc93201f75c6b536b42002e Mon Sep 17 00:00:00 2001 From: Mehul Mathur Date: Fri, 16 Aug 2024 06:27:02 +0000 Subject: [PATCH 5/5] fix: remove rustls conversion from errata --- src/core/errata.rs | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/core/errata.rs b/src/core/errata.rs index e10ba0d5cd..7cc493ef3b 100644 --- a/src/core/errata.rs +++ b/src/core/errata.rs @@ -150,15 +150,6 @@ impl From for Errata { } } -impl From for Errata { - fn from(error: rustls::Error) -> Self { - let cli_error = Errata::new("Failed to create TLS Acceptor"); - let message = error.to_string(); - - cli_error.description(message) - } -} - impl From for Errata { fn from(error: anyhow::Error) -> Self { // Convert other errors to Errata