Skip to content

Commit d343032

Browse files
committed
chore(config): add and use ParseError to propagate errors better
1 parent a35ef86 commit d343032

File tree

4 files changed

+79
-24
lines changed

4 files changed

+79
-24
lines changed

src/config/config.rs

Lines changed: 67 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use crate::directive::DirectiveCodec;
1616
use crate::http::Method;
1717
use crate::is_default;
1818
use crate::json::JsonSchema;
19-
use crate::valid::{Valid, Validator};
19+
use crate::valid::{ValidationError, Validator};
2020

2121
#[derive(
2222
Serialize, Deserialize, Clone, Debug, Default, Setters, PartialEq, Eq, schemars::JsonSchema,
@@ -662,26 +662,82 @@ pub struct AddField {
662662
pub path: Vec<String>,
663663
}
664664

665+
#[derive(Debug)]
666+
pub enum ParseError {
667+
Validation(ValidationError<String>),
668+
GraphQL(async_graphql::parser::Error),
669+
Json(serde_json::Error),
670+
Yaml(serde_yaml::Error),
671+
}
672+
673+
impl std::fmt::Display for ParseError {
674+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
675+
match self {
676+
ParseError::Validation(x) => std::fmt::Display::fmt(x, f),
677+
ParseError::GraphQL(x) => std::fmt::Display::fmt(x, f),
678+
ParseError::Json(x) => std::fmt::Display::fmt(x, f),
679+
ParseError::Yaml(x) => std::fmt::Display::fmt(x, f),
680+
}
681+
}
682+
}
683+
684+
impl std::error::Error for ParseError {}
685+
686+
impl From<async_graphql::parser::Error> for ParseError {
687+
fn from(value: async_graphql::parser::Error) -> Self {
688+
Self::GraphQL(value)
689+
}
690+
}
691+
692+
impl From<ValidationError<String>> for ParseError {
693+
fn from(value: ValidationError<String>) -> Self {
694+
Self::Validation(value)
695+
}
696+
}
697+
698+
impl From<serde_json::Error> for ParseError {
699+
fn from(value: serde_json::Error) -> Self {
700+
Self::Json(value)
701+
}
702+
}
703+
704+
impl From<serde_yaml::Error> for ParseError {
705+
fn from(value: serde_yaml::Error) -> Self {
706+
Self::Yaml(value)
707+
}
708+
}
709+
710+
impl From<ParseError> for ValidationError<String> {
711+
fn from(value: ParseError) -> Self {
712+
match value {
713+
ParseError::Validation(x) => x,
714+
ParseError::GraphQL(x) => ValidationError::new(x.to_string()),
715+
ParseError::Json(x) => ValidationError::new(x.to_string()),
716+
ParseError::Yaml(x) => ValidationError::new(x.to_string()),
717+
}
718+
}
719+
}
720+
665721
impl Config {
666-
pub fn from_json(json: &str) -> Result<Self> {
667-
Ok(serde_json::from_str(json)?)
722+
pub fn from_json(json: &str) -> Result<Self, serde_json::Error> {
723+
serde_json::from_str(json)
668724
}
669725

670-
pub fn from_yaml(yaml: &str) -> Result<Self> {
671-
Ok(serde_yaml::from_str(yaml)?)
726+
pub fn from_yaml(yaml: &str) -> Result<Self, serde_yaml::Error> {
727+
serde_yaml::from_str(yaml)
672728
}
673729

674-
pub fn from_sdl(sdl: &str) -> Valid<Self, String> {
730+
pub fn from_sdl(sdl: &str) -> Result<Self, ParseError> {
675731
let doc = async_graphql::parser::parse_schema(sdl);
676732
match doc {
677-
Ok(doc) => from_document(doc),
678-
Err(e) => Valid::fail(e.to_string()),
733+
Ok(doc) => Ok(from_document(doc).to_result()?),
734+
Err(e) => Err(e.into()),
679735
}
680736
}
681737

682-
pub fn from_source(source: Source, schema: &str) -> Result<Self> {
738+
pub fn from_source(source: Source, schema: &str) -> Result<Self, ParseError> {
683739
match source {
684-
Source::GraphQL => Ok(Config::from_sdl(schema).to_result()?),
740+
Source::GraphQL => Config::from_sdl(schema),
685741
Source::Json => Ok(Config::from_json(schema)?),
686742
Source::Yml => Ok(Config::from_yaml(schema)?),
687743
}
@@ -735,7 +791,7 @@ mod tests {
735791

736792
#[test]
737793
fn test_from_sdl_empty() {
738-
let actual = Config::from_sdl("type Foo {a: Int}").to_result().unwrap();
794+
let actual = Config::from_sdl("type Foo {a: Int}").unwrap();
739795
let expected = Config::default().types(vec![(
740796
"Foo",
741797
Type::default().fields(vec![("a", Field::int())]),

testconv/src/main.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ async fn generate_client_snapshot(file_stem: &str, config: &ConfigModule) {
6262
}
6363

6464
async fn generate_client_snapshot_sdl(file_stem: &str, sdl: &str, reader: &ConfigReader) {
65-
let config = Config::from_sdl(sdl).to_result().unwrap();
65+
let config = Config::from_sdl(sdl).unwrap();
6666
let config = reader.resolve(config, None).await.unwrap();
6767
generate_client_snapshot(file_stem, &config).await
6868
}
@@ -87,7 +87,7 @@ async fn generate_merged_snapshot(file_stem: &str, config: &Config) {
8787
}
8888

8989
async fn generate_merged_snapshot_sdl(file_stem: &str, sdl: &str) {
90-
let config = Config::from_sdl(sdl).to_result().unwrap();
90+
let config = Config::from_sdl(sdl).unwrap();
9191
generate_merged_snapshot(file_stem, &config).await
9292
}
9393

tests/execution_spec.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use tailcall::config::{Config, ConfigModule, Source};
2424
use tailcall::http::{handle_request, AppContext, Method, Response};
2525
use tailcall::print_schema::print_schema;
2626
use tailcall::target_runtime::TargetRuntime;
27-
use tailcall::valid::{Cause, ValidationError, Validator as _};
27+
use tailcall::valid::{Cause, ValidationError};
2828
use tailcall::{EnvIO, HttpIO};
2929
use url::Url;
3030

@@ -580,7 +580,7 @@ async fn assert_spec(spec: ExecutionSpec) {
580580
panic!("Cannot use \"sdl error\" directive with a non-GraphQL server block.");
581581
}
582582

583-
let config = Config::from_sdl(content).to_result();
583+
let config = Config::from_sdl(content);
584584

585585
let config = match config {
586586
Ok(config) => {
@@ -594,7 +594,7 @@ async fn assert_spec(spec: ExecutionSpec) {
594594
Err(e) => Err(ValidationError::new(e.to_string())),
595595
}
596596
}
597-
Err(e) => Err(e),
597+
Err(e) => Err(e.into()),
598598
};
599599

600600
match config {

tests/graphql_spec.rs

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ fn test_config_identity() -> std::io::Result<()> {
247247
let content = spec.find_source(Tag::ServerSDL);
248248
let content = content.as_str();
249249
let expected = content;
250-
let config = Config::from_sdl(content).to_result().unwrap();
250+
let config = Config::from_sdl(content).unwrap();
251251
let actual = config.to_sdl();
252252

253253
if spec
@@ -286,7 +286,7 @@ async fn test_server_to_client_sdl() -> std::io::Result<()> {
286286
let expected = expected.as_str();
287287
let content = spec.find_source(Tag::ServerSDL);
288288
let content = content.as_str();
289-
let config = Config::from_sdl(content).to_result().unwrap();
289+
let config = Config::from_sdl(content).unwrap();
290290
let upstream = Upstream::try_from(config.upstream.clone()).unwrap();
291291
let runtime = init_runtime(&upstream, None);
292292
let reader = ConfigReader::init(runtime);
@@ -322,9 +322,8 @@ async fn test_execution() -> std::io::Result<()> {
322322
.into_iter()
323323
.map(|spec| {
324324
tokio::spawn(async move {
325-
let mut config = Config::from_sdl(spec.find_source(Tag::ServerSDL).as_str())
326-
.to_result()
327-
.unwrap();
325+
let mut config =
326+
Config::from_sdl(spec.find_source(Tag::ServerSDL).as_str()).unwrap();
328327
config.server.query_validation = Some(false);
329328
let config_set = ConfigModule::from(config);
330329
let blueprint = Valid::from(Blueprint::try_from(&config_set))
@@ -379,7 +378,7 @@ async fn test_failures_in_client_sdl() -> std::io::Result<()> {
379378
let content = content.as_str();
380379
println!("{:?}", spec.path);
381380

382-
let config = Config::from_sdl(content).to_result();
381+
let config = Config::from_sdl(content);
383382
let actual = match config {
384383
Ok(config) => {
385384
let upstream = Upstream::try_from(config.upstream.clone()).unwrap();
@@ -395,7 +394,7 @@ async fn test_failures_in_client_sdl() -> std::io::Result<()> {
395394
Err(e) => Err(ValidationError::new(e.to_string())),
396395
}
397396
}
398-
Err(e) => Err(e),
397+
Err(e) => Err(e.into()),
399398
};
400399
match actual {
401400
Err(cause) => {
@@ -440,7 +439,7 @@ fn test_merge_sdl() -> std::io::Result<()> {
440439
let expected = expected.as_str();
441440
let content = spec
442441
.get_sources(Tag::ServerSDL)
443-
.map(|s| Config::from_sdl(s).to_result().unwrap())
442+
.map(|s| Config::from_sdl(s).unwrap())
444443
.collect::<Vec<_>>();
445444
let config = content
446445
.iter()

0 commit comments

Comments
 (0)