Upgraded Err library
This commit is contained in:
parent
d814091e73
commit
c59526086f
|
@ -0,0 +1,8 @@
|
||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# Editor-based HTTP Client requests
|
||||||
|
/httpRequests/
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
|
@ -0,0 +1,11 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="EMPTY_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/err.iml" filepath="$PROJECT_DIR$/.idea/err.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
|
@ -12,3 +12,5 @@ repository = "https://github.com/franklinblanco/err.git"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
|
thiserror = "1.0.48"
|
||||||
|
sqlx = { version = "0.7", features = ["json"] }
|
141
src/lib.rs
141
src/lib.rs
|
@ -1,5 +1,54 @@
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
use serde::{Serialize, Deserialize};
|
use serde::{Serialize, Deserialize, Serializer};
|
||||||
|
use serde::ser::SerializeMap;
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Default)]
|
||||||
|
pub struct Trace {
|
||||||
|
pub line: u32,
|
||||||
|
pub function: String,
|
||||||
|
pub file: String,
|
||||||
|
pub service: String,
|
||||||
|
}
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
|
pub struct Traces(pub Vec<Trace>);
|
||||||
|
#[derive(Serialize, Debug)]
|
||||||
|
pub struct Error {
|
||||||
|
pub trace: Traces,
|
||||||
|
#[serde(rename = "messageResource")]
|
||||||
|
pub message_resource: MessageResource,
|
||||||
|
#[serde(rename = "errorType")]
|
||||||
|
pub error_type: ErrorType,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Error {
|
||||||
|
pub fn new(trace: Trace) -> Self {
|
||||||
|
Self {
|
||||||
|
trace: Traces(Vec::from([trace])),
|
||||||
|
message_resource: MessageResource::new("errors.backend.common.default", "We still don't have an error defined for this."),
|
||||||
|
error_type: ErrorType::Unspecified,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn push_trace(mut self, trace: Trace) -> Self {
|
||||||
|
self.trace.0.push(trace);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
pub fn push_error(mut self, error: Error) -> Self {
|
||||||
|
self.error_type = ErrorType::Nested(Box::new(error));
|
||||||
|
self
|
||||||
|
}
|
||||||
|
pub fn key(mut self, key: Option<impl ToString>) -> Self {
|
||||||
|
self.message_resource.key = match key {
|
||||||
|
None => None,
|
||||||
|
Some(key) => Some(key.to_string()),
|
||||||
|
};
|
||||||
|
self
|
||||||
|
}
|
||||||
|
pub fn message(mut self, message: impl ToString) -> Self {
|
||||||
|
self.message_resource.message = message.to_string();
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// This is for sending errors back from requests conveniently.
|
/// This is for sending errors back from requests conveniently.
|
||||||
/// This struct contains an optional key just in
|
/// This struct contains an optional key just in
|
||||||
|
@ -41,27 +90,73 @@ impl Default for MessageResource{
|
||||||
}
|
}
|
||||||
/// This is supposed to be used whenever you have an error in your code and want to be more specific about it.
|
/// This is supposed to be used whenever you have an error in your code and want to be more specific about it.
|
||||||
/// Fits in with most CRUD web apps. What you send back to the client is a MessageResource, not the error itself!
|
/// Fits in with most CRUD web apps. What you send back to the client is a MessageResource, not the error itself!
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Serialize, Debug, Error)]
|
||||||
pub enum Error {
|
pub enum ErrorType {
|
||||||
Network(MessageResource),
|
#[error("Network Error")]
|
||||||
IO(MessageResource),
|
Network,
|
||||||
Privilege(MessageResource),
|
#[error("IO error")]
|
||||||
UnexpectedStatusCode(u16, u16, Vec<MessageResource>),
|
IO,
|
||||||
Serde(MessageResource),
|
#[error("Privilege Error")]
|
||||||
Parser(MessageResource),
|
Privilege,
|
||||||
Unspecified
|
#[error("Unexpected Status Code. Expected: {0} Actual: {1}")]
|
||||||
|
UnexpectedStatusCode(u16, u16),
|
||||||
|
#[error("Serde Error. Attempted to Serialize/Deserialize String: {0}")]
|
||||||
|
Serde(String),
|
||||||
|
#[error("Parsing error.")]
|
||||||
|
Parser,
|
||||||
|
#[error("Service Error: {0}")]
|
||||||
|
Service(ServiceError),
|
||||||
|
#[error("Unspecified Error")]
|
||||||
|
Unspecified,
|
||||||
|
#[error("Unexpected Error: {0}")]
|
||||||
|
Unexpected(String),
|
||||||
|
#[error("Nested Error: {0:?}")]
|
||||||
|
Nested(Box<Error>),
|
||||||
}
|
}
|
||||||
impl Display for Error {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
#[derive(Error, Serialize, Debug)]
|
||||||
match self {
|
pub enum ServiceError {
|
||||||
Error::Network(message) => write!(f, "Error of type Network. MessageResource: {message}"),
|
/// Used to return a simple error from FromStr implementations.
|
||||||
Error::IO(message) => write!(f, "Error of type IO. MessageResource: {message}"),
|
#[error("Error parsing string into value")]
|
||||||
Error::Privilege(message) => write!(f, "Error of type Privilege. MessageResource: {message}"),
|
FromStrError,
|
||||||
Error::UnexpectedStatusCode(expected, actual, messages) => write!(f, "Error of type UnexpectedStatusCode. Expected: {expected}, Actual: {actual}, MessageResources: {:#?}", messages),
|
/// Every error that is returned from a DAO operation.
|
||||||
Error::Serde(message) => write!(f, "Error of type Serialization/Deserialization. MessageResource: {message}"),
|
#[error("Error from the Database: {0}")]
|
||||||
Error::Unspecified => write!(f, "Error of type Unspecified."),
|
#[serde(serialize_with = "ser_with")]
|
||||||
Error::Parser(message) => write!(f, "Error of type Parser. MessageResource: {message}"),
|
DatabaseError(#[from] sqlx::Error),
|
||||||
}
|
/// A vec of ValidationErrors
|
||||||
}
|
#[error("Validation Errors: {0:?}")]
|
||||||
|
ValidationErrors(Vec<ValidationError>),
|
||||||
|
/// Something already exists. That something should be {0}
|
||||||
|
/// Example: "User" "Credential"
|
||||||
|
#[error("Error {0} Already exists.")]
|
||||||
|
AlreadyExistsError(String),
|
||||||
|
/// Example: "User with id X"
|
||||||
|
#[error("{0} Not found.")]
|
||||||
|
NotFoundError(String),
|
||||||
|
/// Used to specify authentication error.
|
||||||
|
/// Example: Password incorrect for user
|
||||||
|
#[error("Credential supplied is incorrect. {0}")]
|
||||||
|
IncorrectCredentialError(String),
|
||||||
|
#[error("Too many credentials supplied, maximum is 3.")]
|
||||||
|
TooManyCredentialsError,
|
||||||
|
/// Used for anything else.
|
||||||
|
#[error("Unexpected Error: {0}")]
|
||||||
|
UnexpectedError(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Any string validation error such as Phone number validation or email, etc...
|
||||||
|
/// Reason should be a Key for internationalization
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Error)]
|
||||||
|
#[error("Error validating `{what}`. Reason: {reason}")]
|
||||||
|
pub struct ValidationError {
|
||||||
|
pub what: String,
|
||||||
|
pub reason: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn ser_with<S>(id: &sqlx::Error, s: S) -> Result<S::Ok, S::Error> where
|
||||||
|
S: Serializer,
|
||||||
|
{
|
||||||
|
let mut ser = s.serialize_map(Some(1))?;
|
||||||
|
ser.serialize_entry("$oid", &id.to_string())?;
|
||||||
|
ser.end()
|
||||||
}
|
}
|
||||||
impl std::error::Error for Error {}
|
|
Loading…
Reference in New Issue