Files
siren/service/src/lib.rs
2023-10-23 16:17:13 -04:00

147 lines
4.0 KiB
Rust

use actix_web::{ResponseError, HttpResponse};
use diesel::result::Error as DieselError;
use reqwest::StatusCode;
use serde::{Serialize, Deserialize};
use std::fmt;
#[derive(Serialize, Deserialize)]
pub struct Message {
pub id: String,
pub guild_id: i64,
pub channel_id: i64,
pub user_id: i64,
pub created: i64,
pub model: String,
pub request: String,
pub response: String,
pub request_tags: Vec<String>,
pub response_tags: Vec<String>,
}
#[derive(Serialize, Deserialize)]
pub struct GetResponse<T> {
pub data: T,
#[serde(skip_serializing_if = "Option::is_none")]
pub metadata: Option<Metadata>
}
#[derive(Serialize, Deserialize)]
pub struct Metadata {
pub total: i32,
pub limit: i32,
pub page: i32,
pub pages: i32
}
#[derive(Debug, Deserialize, Serialize)]
pub struct ServiceError {
pub status: u16,
pub message: String,
}
impl ServiceError {
pub fn new(error_status_code: u16, error_message: String) -> ServiceError {
ServiceError {
status: error_status_code,
message: error_message,
}
}
}
impl fmt::Display for ServiceError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str(self.message.as_str())
}
}
impl From<DieselError> for ServiceError {
fn from(error: DieselError) -> ServiceError {
match error {
DieselError::DatabaseError(kind, err) => {
match kind {
diesel::result::DatabaseErrorKind::UniqueViolation => {
ServiceError::new(409, err.message().to_string())
},
_ => ServiceError::new(500, err.message().to_string())
}
},
DieselError::NotFound => {
ServiceError::new(404, "The record was not found".to_string())
},
DieselError::SerializationError(err) => {
ServiceError::new(422, err.to_string())
},
err => ServiceError::new(500, format!("Unknown database error: {}", err)),
}
}
}
impl From<reqwest::Error> for ServiceError {
fn from(error: reqwest::Error) -> ServiceError {
ServiceError::new(500, format!("Unknown reqwest error: {}", error))
}
}
impl From<serde_json::Error> for ServiceError {
fn from(error: serde_json::Error) -> ServiceError {
ServiceError::new(500, format!("Unknown serde_json error: {}", error))
}
}
impl From<serenity::Error> for ServiceError {
fn from(error: serenity::Error) -> ServiceError {
ServiceError::new(500, format!("Unknown serenity error: {}", error))
}
}
impl From<argon2::password_hash::Error> for ServiceError {
fn from(error: argon2::password_hash::Error) -> ServiceError {
ServiceError::new(500, format!("Unknown argon2 error: {}", error))
}
}
impl From<jsonwebtoken::errors::Error> for ServiceError {
fn from(error: jsonwebtoken::errors::Error) -> ServiceError {
ServiceError::new(500, format!("Unknown jsonwebtoken error: {}", error))
}
}
impl From<redis::RedisError> for ServiceError {
fn from(error: redis::RedisError) -> ServiceError {
ServiceError::new(500, format!("Unknown redis error: {}", error))
}
}
impl From<s3::error::S3Error> for ServiceError {
fn from(error: s3::error::S3Error) -> ServiceError {
match error {
s3::error::S3Error::Http(code, message) => {
ServiceError::new(code, message)
},
_ => ServiceError::new(500, format!("Unknown s3 error: {}", error))
}
}
}
impl From<s3::creds::error::CredentialsError> for ServiceError {
fn from(error: s3::creds::error::CredentialsError) -> ServiceError {
ServiceError::new(500, format!("Unknown credentials error: {}", error))
}
}
impl ResponseError for ServiceError {
fn error_response(&self) -> HttpResponse {
let status_code = match StatusCode::from_u16(self.status) {
Ok(status_code) => status_code,
Err(_) => StatusCode::INTERNAL_SERVER_ERROR,
};
let error_message = match status_code.as_u16() < 500 {
true => self.message.clone(),
false => "Internal server error".to_string(),
};
HttpResponse::build(status_code).json(serde_json::json!({ "status": status_code.as_u16(), "message": error_message }))
}
}