mod common;
use apollo_errors::error_catalog;
use insta::assert_json_snapshot;
fn find_error_by_name<'a>(
errors: &'a [serde_json::Value],
name: &str,
) -> Option<&'a serde_json::Value> {
errors
.iter()
.find(|e| e.get("typeName").and_then(|v| v.as_str()) == Some(name))
}
#[test]
fn test_simple_error_catalog() {
let catalog = error_catalog();
let catalog_json = serde_json::to_value(&catalog).unwrap();
let errors = catalog_json.as_array().unwrap();
let simple_error = find_error_by_name(errors, "SimpleError").unwrap();
assert_json_snapshot!(simple_error, @r#"
{
"typeName": "SimpleError",
"variants": [
{
"code": "errors::simple",
"fields": [],
"httpStatus": 500,
"message": "Something went wrong",
"name": "Simple"
},
{
"code": "errors::another",
"fields": [],
"httpStatus": 500,
"message": "Another error occurred",
"name": "Another"
}
]
}
"#);
}
#[test]
fn test_error_with_fields_catalog() {
let catalog = error_catalog();
let catalog_json = serde_json::to_value(&catalog).unwrap();
let errors = catalog_json.as_array().unwrap();
let error_with_fields = find_error_by_name(errors, "ErrorWithFields").unwrap();
assert_json_snapshot!(error_with_fields, @r###"
{
"typeName": "ErrorWithFields",
"variants": [
{
"code": "config::invalid_port",
"fields": [
{
"isExtension": true,
"outputName": "port",
"rustName": "port",
"ty": "u16"
},
{
"isExtension": true,
"outputName": "config_file",
"rustName": "config_file",
"ty": "String"
}
],
"httpStatus": 500,
"message": "Invalid port",
"name": "InvalidPort"
},
{
"code": "config::missing",
"fields": [
{
"isExtension": true,
"outputName": "expected_path",
"rustName": "expected_path",
"ty": "String"
}
],
"httpStatus": 500,
"message": "Missing configuration",
"name": "MissingConfig"
}
]
}
"###);
}
#[test]
fn test_error_with_status_catalog() {
let catalog = error_catalog();
let catalog_json = serde_json::to_value(&catalog).unwrap();
let errors = catalog_json.as_array().unwrap();
let error_with_status = find_error_by_name(errors, "ErrorWithStatus").unwrap();
assert_json_snapshot!(error_with_status, @r#"
{
"typeName": "ErrorWithStatus",
"variants": [
{
"code": "resource::not_found",
"fields": [],
"httpStatus": 404,
"message": "Resource not found",
"name": "NotFound"
},
{
"code": "request::bad",
"fields": [],
"httpStatus": 400,
"message": "Bad request",
"name": "BadRequest"
},
{
"code": "service::unavailable",
"fields": [],
"httpStatus": 503,
"message": "Service unavailable",
"name": "ServiceUnavailable"
},
{
"code": "internal::error",
"fields": [],
"httpStatus": 500,
"message": "Internal error",
"name": "InternalError"
}
]
}
"#);
}
#[test]
fn test_error_with_help_catalog() {
let catalog = error_catalog();
let catalog_json = serde_json::to_value(&catalog).unwrap();
let errors = catalog_json.as_array().unwrap();
let error_with_help = find_error_by_name(errors, "ErrorWithHelp").unwrap();
assert_json_snapshot!(error_with_help, @r#"
{
"typeName": "ErrorWithHelp",
"variants": [
{
"code": "config::error",
"fields": [],
"help": "Check your configuration file",
"httpStatus": 500,
"message": "Configuration error",
"name": "ConfigError",
"severity": "warning",
"url": "https://docs.example.com/errors/config"
}
]
}
"#);
}
#[test]
fn test_transparent_wrapper_error_catalog() {
let catalog = error_catalog();
let catalog_json = serde_json::to_value(&catalog).unwrap();
let errors = catalog_json.as_array().unwrap();
let transparent_wrapper = find_error_by_name(errors, "TransparentWrapperError").unwrap();
assert_json_snapshot!(transparent_wrapper, @r###"
{
"typeName": "TransparentWrapperError",
"variants": [
{
"code": "app::error",
"fields": [],
"httpStatus": 500,
"message": "Application error",
"name": "ApplicationError"
},
{
"code": "db::connection_failed",
"fields": [],
"help": "Check your database credentials",
"httpStatus": 503,
"message": "Database connection failed",
"name": "DatabaseError"
},
{
"code": "network::timeout",
"fields": [
{
"isExtension": true,
"outputName": "timeout_ms",
"rustName": "timeout_ms",
"ty": "u64"
}
],
"httpStatus": 504,
"message": "Network timeout after {timeout_ms}ms",
"name": "NetworkTimeout"
}
]
}
"###);
}
#[test]
fn test_transparent_to_struct_error_catalog() {
let catalog = error_catalog();
let catalog_json = serde_json::to_value(&catalog).unwrap();
let errors = catalog_json.as_array().unwrap();
let transparent_to_struct = find_error_by_name(errors, "TransparentToStructError").unwrap();
assert_json_snapshot!(transparent_to_struct, @r###"
{
"typeName": "TransparentToStructError",
"variants": [
{
"code": "wrapper::direct",
"fields": [],
"httpStatus": 500,
"message": "Direct enum error",
"name": "Direct"
},
{
"code": "structs::config_error",
"fields": [
{
"isExtension": true,
"outputName": "port",
"rustName": "port",
"ty": "u16"
},
{
"isExtension": true,
"outputName": "config_path",
"rustName": "config_path",
"ty": "String"
}
],
"help": "Check your configuration file",
"httpStatus": 400,
"message": "Configuration error: invalid port {port}",
"name": "ConfigStructError"
},
{
"code": "structs::simple",
"fields": [],
"httpStatus": 500,
"message": "Simple struct error occurred",
"name": "SimpleStructError"
}
]
}
"###);
}