From 5a8683b3bce3c6fd9810b8e7384ac3fae6a04a21 Mon Sep 17 00:00:00 2001 From: Mike Cooper Date: Wed, 12 Dec 2018 14:19:16 -0800 Subject: [PATCH] Move errors to a separate file --- src/errors.rs | 60 +++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 67 ++++++--------------------------------------------- 2 files changed, 68 insertions(+), 59 deletions(-) create mode 100644 src/errors.rs diff --git a/src/errors.rs b/src/errors.rs new file mode 100644 index 0000000..391a3b4 --- /dev/null +++ b/src/errors.rs @@ -0,0 +1,60 @@ +use actix_web::HttpResponse; +use maxminddb::{self, MaxMindDBError}; +use serde_derive::Serialize; +use std::fmt; + +#[derive(Debug, Serialize)] +pub struct ClassifyError { + message: String, +} + +impl ClassifyError { + pub fn new>(message: M) -> Self { + let message = message.into(); + Self { message } + } + + pub fn from_source(source: S, err: E) -> Self { + Self { + message: format!("{}: {}", source, err), + } + } +} + +// Use default implementation of Error +impl std::error::Error for ClassifyError {} + +impl fmt::Display for ClassifyError { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + write!(formatter, "{:?}", self)?; + Ok(()) + } +} + +impl actix_web::error::ResponseError for ClassifyError { + fn error_response(&self) -> HttpResponse { + HttpResponse::InternalServerError().json(self) + } +} + +impl From for ClassifyError { + fn from(error: MaxMindDBError) -> Self { + match error { + MaxMindDBError::AddressNotFoundError(msg) => ClassifyError { + message: format!("AddressNotFound: {}", msg), + }, + MaxMindDBError::InvalidDatabaseError(msg) => ClassifyError { + message: format!("InvalidDatabaseError: {}", msg), + }, + MaxMindDBError::IoError(msg) => ClassifyError { + message: format!("IoError: {}", msg), + }, + MaxMindDBError::MapError(msg) => ClassifyError { + message: format!("MapError: {}", msg), + }, + MaxMindDBError::DecodingError(msg) => ClassifyError { + message: format!("DecodingError: {}", msg), + }, + } + } +} diff --git a/src/main.rs b/src/main.rs index 95ea2e2..99b67ba 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,7 +11,11 @@ use listenfd::ListenFd; use maxminddb::{self, geoip2, MaxMindDBError}; use serde::Serializer; use serde_derive::Serialize; -use std::{env, fmt, net::IpAddr, path::PathBuf, process}; +use std::{env, net::IpAddr, path::PathBuf, process}; + +use crate::errors::ClassifyError; + +mod errors; struct State { geoip: actix::Addr, @@ -65,28 +69,6 @@ fn main() { sys.run(); } -impl From for ClassifyError { - fn from(error: MaxMindDBError) -> Self { - match error { - MaxMindDBError::AddressNotFoundError(msg) => ClassifyError { - message: format!("AddressNotFound: {}", msg), - }, - MaxMindDBError::InvalidDatabaseError(msg) => ClassifyError { - message: format!("InvalidDatabaseError: {}", msg), - }, - MaxMindDBError::IoError(msg) => ClassifyError { - message: format!("IoError: {}", msg), - }, - MaxMindDBError::MapError(msg) => ClassifyError { - message: format!("MapError: {}", msg), - }, - MaxMindDBError::DecodingError(msg) => ClassifyError { - message: format!("DecodingError: {}", msg), - }, - } - } -} - struct GeoIpActor { reader: maxminddb::OwnedReader<'static>, } @@ -125,35 +107,6 @@ impl actix::Message for CountryForIp { type Result = Result, ClassifyError>; } -#[derive(Debug, Serialize)] -struct ClassifyError { - message: String, -} - -impl ClassifyError { - fn from(source: S, err: E) -> Self { - ClassifyError { - message: format!("{}: {}", source, err), - } - } -} - -// Use default implementation of Error -impl std::error::Error for ClassifyError {} - -impl fmt::Display for ClassifyError { - fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - write!(formatter, "{:?}", self)?; - Ok(()) - } -} - -impl actix_web::error::ResponseError for ClassifyError { - fn error_response(&self) -> HttpResponse { - HttpResponse::InternalServerError().json(self) - } -} - #[derive(Serialize)] struct ClientClassification { request_time: DateTime, @@ -190,12 +143,10 @@ fn index(req: &HttpRequest) -> Box = req .connection_info() .remote() - .ok_or(ClassifyError { - message: "no ip".to_string(), - }) + .ok_or_else(|| ClassifyError::new("no ip")) .and_then(|remote| { remote.parse().map_err(|err| { - ClassifyError::from(format!("IP ParseError for remote '{}'", remote), err) + ClassifyError::from_source(format!("IP ParseError for remote '{}'", remote), err) }) }); let ip: IpAddr = match ip_res { @@ -224,8 +175,6 @@ fn index(req: &HttpRequest) -> Box Ok(HttpResponse::InternalServerError().body(format!("{}", err))), } }) - .map_err(|err| ClassifyError { - message: format!("Future failure: {}", err), - }), + .map_err(|err| ClassifyError::from_source("Future failure", err)), ) }