use rocket::http::ContentType; use rocket::request::Request; use rocket::response::{self, Responder, Response}; use rspotify::client::ClientError; use rspotify::client::Spotify; use std::collections::HashMap; use std::io::Cursor; use std::sync::{MutexGuard, PoisonError}; use tokio_postgres::Error as DbError; #[derive(Debug)] pub enum Error { Postgres(DbError), Spotify(ClientError), Misc(String), } impl From for Error { fn from(error: DbError) -> Self { Error::Postgres(error) } } impl From for Error { fn from(error: ClientError) -> Self { Error::Spotify(error) } } impl From<&str> for Error { fn from(error: &str) -> Self { Error::Misc(error.to_owned()) } } impl From for Error { fn from(error: String) -> Self { Error::Misc(error) } } impl<'a> From>>> for Error { fn from(error: PoisonError>>) -> Self { Error::Misc(format!("failed to lock the client mutex: {:?}", error)) } } impl<'a> From>> for Error { fn from(error: PoisonError>) -> Self { Error::Misc(format!("failed to lock the client mutex: {:?}", error)) } } impl<'a> From for Error { fn from(error: std::option::NoneError) -> Self { Error::Misc(format!("tried to unwrap none at: {:?}", error)) } } impl<'a> Responder<'a, 'a> for Error { fn respond_to(self, _: &Request) -> response::Result<'a> { let response = match self { Error::Postgres(e) => format!("DB Error: {:?}", e), Error::Spotify(e) => format!("Spotify Error: {:?}", e), Error::Misc(e) => format!("Error: {}", e), }; Response::build() .header(ContentType::Plain) .status(rocket::http::Status::raw(500)) .sized_body(response.len(), Cursor::new(response)) .ok() } }