Error types consolidation

This commit is contained in:
Antoine Gersant 2024-08-01 00:09:21 -07:00
parent 8f2566f574
commit cd45836924
16 changed files with 185 additions and 350 deletions

View file

@ -1,7 +1,7 @@
use std::fs;
use std::path::PathBuf;
use crate::db::{self, DB};
use crate::db::DB;
use crate::paths::Paths;
pub mod config;
@ -22,15 +22,105 @@ pub mod test;
#[derive(thiserror::Error, Debug)]
pub enum Error {
#[error(transparent)]
Collection(#[from] index::Error),
ThreadPoolBuilder(#[from] rayon::ThreadPoolBuildError),
#[error(transparent)]
Config(#[from] config::Error),
#[error(transparent)]
Database(#[from] db::Error),
ThreadJoining(#[from] tokio::task::JoinError),
#[error("Filesystem error for `{0}`: `{1}`")]
Io(PathBuf, std::io::Error),
#[error(transparent)]
Settings(#[from] settings::Error),
Ape(#[from] ape::Error),
#[error("ID3 error in `{0}`: `{1}`")]
Id3(PathBuf, id3::Error),
#[error("Metaflac error in `{0}`: `{1}`")]
Metaflac(PathBuf, metaflac::Error),
#[error("Mp4aMeta error in `{0}`: `{1}`")]
Mp4aMeta(PathBuf, mp4ameta::Error),
#[error(transparent)]
Opus(#[from] opus_headers::ParseError),
#[error(transparent)]
Vorbis(#[from] lewton::VorbisError),
#[error("Could not find a Vorbis comment within flac file")]
VorbisCommentNotFoundInFlacFile,
#[error("Could not read thumbnail image in `{0}`:\n\n{1}")]
Image(PathBuf, image::error::ImageError),
#[error("This file format is not supported: {0}")]
UnsupportedFormat(&'static str),
#[error(transparent)]
Database(#[from] sqlx::Error),
#[error("Could not initialize database connection pool")]
ConnectionPoolBuild,
#[error("Could not acquire database connection from pool")]
ConnectionPool,
#[error("Could not apply database migrations: {0}")]
Migration(sqlx::migrate::MigrateError),
#[error("DDNS update query failed with HTTP status code `{0}`")]
UpdateQueryFailed(u16),
#[error("DDNS update query failed due to a transport error")]
UpdateQueryTransport,
#[error("Auth secret does not have the expected format")]
AuthenticationSecretInvalid,
#[error("Missing auth secret")]
AuthenticationSecretNotFound,
#[error("Missing settings")]
MiscSettingsNotFound,
#[error("Index album art pattern is not a valid regex")]
IndexAlbumArtPatternInvalid,
#[error(transparent)]
Toml(#[from] toml::de::Error),
#[error("Could not deserialize collection")]
IndexDeserializationError,
#[error("Could not serialize collection")]
IndexSerializationError,
#[error("The following virtual path could not be mapped to a real path: `{0}`")]
CouldNotMapToRealPath(PathBuf),
#[error("User not found")]
UserNotFound,
#[error("Directory not found: {0}")]
DirectoryNotFound(PathBuf),
#[error("Artist not found")]
ArtistNotFound,
#[error("Album not found")]
AlbumNotFound,
#[error("Song not found")]
SongNotFound,
#[error("Playlist not found")]
PlaylistNotFound,
#[error("No embedded artwork was found in `{0}`")]
EmbeddedArtworkNotFound(PathBuf),
#[error("Cannot use empty username")]
EmptyUsername,
#[error("Cannot use empty password")]
EmptyPassword,
#[error("Username does not exist")]
IncorrectUsername,
#[error("Password does not match username")]
IncorrectPassword,
#[error("Invalid auth token")]
InvalidAuthToken,
#[error("Incorrect authorization scope")]
IncorrectAuthorizationScope,
#[error("Last.fm session key is missing")]
MissingLastFMSessionKey,
#[error("Failed to hash password")]
PasswordHashing,
#[error("Failed to encode authorization token")]
AuthorizationTokenEncoding,
#[error("Failed to encode Branca token")]
BrancaTokenEncoding,
#[error("Failed to authenticate with last.fm")]
ScrobblerAuthentication(rustfm_scrobble::ScrobblerError),
#[error("Failed to emit last.fm scrobble")]
Scrobble(rustfm_scrobble::ScrobblerError),
#[error("Failed to emit last.fm now playing update")]
NowPlaying(rustfm_scrobble::ScrobblerError),
}
#[derive(Clone)]

View file

@ -1,24 +1,7 @@
use serde::Deserialize;
use std::io::Read;
use std::path::{Path, PathBuf};
use std::{io::Read, path::Path};
use crate::app::{ddns, settings, user, vfs};
#[derive(thiserror::Error, Debug)]
pub enum Error {
#[error(transparent)]
Ddns(#[from] ddns::Error),
#[error("Filesystem error for `{0}`: `{1}`")]
Io(PathBuf, std::io::Error),
#[error(transparent)]
Settings(#[from] settings::Error),
#[error(transparent)]
Toml(#[from] toml::de::Error),
#[error(transparent)]
User(#[from] user::Error),
#[error(transparent)]
Vfs(#[from] vfs::Error),
}
use crate::app::{ddns, settings, user, vfs, Error};
#[derive(Default, Deserialize)]
pub struct Config {

View file

@ -3,22 +3,11 @@ use log::{debug, error};
use serde::{Deserialize, Serialize};
use std::time::Duration;
use crate::db::{self, DB};
use crate::app::Error;
use crate::db::DB;
const DDNS_UPDATE_URL: &str = "https://ydns.io/api/v1/update/";
#[derive(thiserror::Error, Debug)]
pub enum Error {
#[error("DDNS update query failed with HTTP status code `{0}`")]
UpdateQueryFailed(u16),
#[error("DDNS update query failed due to a transport error")]
UpdateQueryTransport,
#[error(transparent)]
DatabaseConnection(#[from] db::Error),
#[error(transparent)]
Database(#[from] sqlx::Error),
}
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)]
pub struct Config {
pub ddns_host: String,

View file

@ -2,31 +2,12 @@ use id3::TagLike;
use lewton::inside_ogg::OggStreamReader;
use log::error;
use std::fs;
use std::path::{Path, PathBuf};
use std::path::Path;
use crate::app::Error;
use crate::utils;
use crate::utils::AudioFormat;
#[derive(thiserror::Error, Debug)]
pub enum Error {
#[error(transparent)]
Ape(#[from] ape::Error),
#[error(transparent)]
Id3(#[from] id3::Error),
#[error("Filesystem error for `{0}`: `{1}`")]
Io(PathBuf, std::io::Error),
#[error(transparent)]
Metaflac(#[from] metaflac::Error),
#[error(transparent)]
Mp4aMeta(#[from] mp4ameta::Error),
#[error(transparent)]
Opus(#[from] opus_headers::ParseError),
#[error(transparent)]
Vorbis(#[from] lewton::VorbisError),
#[error("Could not find a Vorbis comment within flac file")]
VorbisCommentNotFoundInFlacFile,
}
#[derive(Debug, Default, Clone, PartialEq, Eq)]
pub struct SongMetadata {
pub disc_number: Option<u32>,
@ -83,13 +64,15 @@ impl ID3Ext for id3::Tag {
}
fn read_id3<P: AsRef<Path>>(path: P) -> Result<SongMetadata, Error> {
let tag = id3::Tag::read_from_path(path).or_else(|error| {
if let Some(tag) = error.partial_tag {
Ok(tag)
} else {
Err(error)
}
})?;
let tag = id3::Tag::read_from_path(&path)
.or_else(|error| {
if let Some(tag) = error.partial_tag {
Ok(tag)
} else {
Err(error)
}
})
.map_err(|e| Error::Id3(path.as_ref().to_owned(), e))?;
let artists = tag.get_text_values("TPE1");
let album_artists = tag.get_text_values("TPE2");
@ -255,7 +238,8 @@ fn read_opus<P: AsRef<Path>>(path: P) -> Result<SongMetadata, Error> {
}
fn read_flac<P: AsRef<Path>>(path: P) -> Result<SongMetadata, Error> {
let tag = metaflac::Tag::read_from_path(path)?;
let tag = metaflac::Tag::read_from_path(&path)
.map_err(|e| Error::Metaflac(path.as_ref().to_owned(), e))?;
let vorbis = tag
.vorbis_comments()
.ok_or(Error::VorbisCommentNotFoundInFlacFile)?;
@ -290,7 +274,8 @@ fn read_flac<P: AsRef<Path>>(path: P) -> Result<SongMetadata, Error> {
}
fn read_mp4<P: AsRef<Path>>(path: P) -> Result<SongMetadata, Error> {
let mut tag = mp4ameta::Tag::read_from_path(path)?;
let mut tag = mp4ameta::Tag::read_from_path(&path)
.map_err(|e| Error::Mp4aMeta(path.as_ref().to_owned(), e))?;
let label_ident = mp4ameta::FreeformIdent::new("com.apple.iTunes", "Label");
Ok(SongMetadata {

View file

@ -7,9 +7,8 @@ use log::{error, info};
use serde::{Deserialize, Serialize};
use tokio::task::spawn_blocking;
use crate::app::scanner;
use crate::app::vfs;
use crate::db::{self, DB};
use crate::app::{scanner, Error};
use crate::db::DB;
mod browser;
mod collection;
@ -18,32 +17,6 @@ mod search;
pub use browser::File;
pub use collection::{Album, AlbumKey, Artist, ArtistKey, Song, SongKey};
#[derive(thiserror::Error, Debug)]
pub enum Error {
#[error("Directory not found: {0}")]
DirectoryNotFound(PathBuf),
#[error("Artist not found")]
ArtistNotFound,
#[error("Album not found")]
AlbumNotFound,
#[error("Song not found")]
SongNotFound,
#[error(transparent)]
Database(#[from] sqlx::Error),
#[error(transparent)]
DatabaseConnection(#[from] db::Error),
#[error(transparent)]
Vfs(#[from] vfs::Error),
#[error("Could not deserialize collection")]
IndexDeserializationError,
#[error("Could not serialize collection")]
IndexSerializationError,
#[error(transparent)]
ThreadPoolBuilder(#[from] rayon::ThreadPoolBuildError),
#[error(transparent)]
ThreadJoining(#[from] tokio::task::JoinError),
}
#[derive(Clone)]
pub struct Manager {
db: DB,

View file

@ -7,7 +7,7 @@ use std::{
use serde::{Deserialize, Serialize};
use trie_rs::{Trie, TrieBuilder};
use crate::app::{index::Error, scanner};
use crate::app::{scanner, Error};
#[derive(Clone, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)]
pub enum File {

View file

@ -2,25 +2,11 @@ use rustfm_scrobble::{Scrobble, Scrobbler};
use std::path::Path;
use user::AuthToken;
use crate::app::{index, user};
use crate::app::{index, user, Error};
const LASTFM_API_KEY: &str = "02b96c939a2b451c31dfd67add1f696e";
const LASTFM_API_SECRET: &str = "0f25a80ceef4b470b5cb97d99d4b3420";
#[derive(thiserror::Error, Debug)]
pub enum Error {
#[error("Failed to authenticate with last.fm")]
ScrobblerAuthentication(rustfm_scrobble::ScrobblerError),
#[error("Failed to emit last.fm scrobble")]
Scrobble(rustfm_scrobble::ScrobblerError),
#[error("Failed to emit last.fm now playing update")]
NowPlaying(rustfm_scrobble::ScrobblerError),
#[error(transparent)]
Query(#[from] index::Error),
#[error(transparent)]
User(#[from] user::Error),
}
#[derive(Clone)]
pub struct Manager {
index_manager: index::Manager,

View file

@ -2,22 +2,8 @@ use core::clone::Clone;
use sqlx::{Acquire, QueryBuilder, Sqlite};
use std::path::PathBuf;
use crate::app::vfs;
use crate::db::{self, DB};
#[derive(thiserror::Error, Debug)]
pub enum Error {
#[error(transparent)]
Database(#[from] sqlx::Error),
#[error(transparent)]
DatabaseConnection(#[from] db::Error),
#[error("User not found")]
UserNotFound,
#[error("Playlist not found")]
PlaylistNotFound,
#[error(transparent)]
Vfs(#[from] vfs::Error),
}
use crate::app::{vfs, Error};
use crate::db::DB;
#[derive(Clone)]
pub struct Manager {
@ -191,7 +177,7 @@ impl Manager {
#[cfg(test)]
mod test {
use std::path::{Path, PathBuf};
use std::path::PathBuf;
use crate::app::test;
use crate::test_name;

View file

@ -11,7 +11,7 @@ use tokio::sync::mpsc::{unbounded_channel, UnboundedSender};
use tokio::sync::Notify;
use tokio::time::Instant;
use crate::app::{formats, index, settings, vfs};
use crate::app::{formats, index, settings, vfs, Error};
#[derive(Debug, PartialEq, Eq)]
pub struct Directory {
@ -53,7 +53,7 @@ impl Scanner {
index_manager: index::Manager,
settings_manager: settings::Manager,
vfs_manager: vfs::Manager,
) -> Result<Self, index::Error> {
) -> Result<Self, Error> {
let scanner = Self {
index_manager,
vfs_manager,
@ -100,7 +100,7 @@ impl Scanner {
});
}
pub async fn update(&mut self) -> Result<(), index::Error> {
pub async fn update(&mut self) -> Result<(), Error> {
let start = Instant::now();
info!("Beginning collection scan");
@ -185,7 +185,7 @@ impl Scan {
}
}
pub async fn start(self) -> Result<(), index::Error> {
pub async fn start(self) -> Result<(), Error> {
let vfs = self.vfs_manager.get_vfs().await?;
let roots = vfs.mounts().clone();

View file

@ -2,23 +2,8 @@ use regex::Regex;
use serde::Deserialize;
use std::time::Duration;
use crate::db::{self, DB};
#[derive(thiserror::Error, Debug)]
pub enum Error {
#[error("Auth secret does not have the expected format")]
AuthenticationSecretInvalid,
#[error("Missing auth secret")]
AuthenticationSecretNotFound,
#[error(transparent)]
DatabaseConnection(#[from] db::Error),
#[error("Missing settings")]
MiscSettingsNotFound,
#[error("Index album art pattern is not a valid regex")]
IndexAlbumArtPatternInvalid,
#[error(transparent)]
Database(#[from] sqlx::Error),
}
use crate::app::Error;
use crate::db::DB;
#[derive(Clone, Default)]
pub struct AuthSecret {

View file

@ -6,26 +6,9 @@ use std::fs::{self, File};
use std::hash::{Hash, Hasher};
use std::path::{Path, PathBuf};
use crate::app::Error;
use crate::utils::{get_audio_format, AudioFormat};
#[derive(thiserror::Error, Debug)]
pub enum Error {
#[error("No embedded artwork was found in `{0}`")]
EmbeddedArtworkNotFound(PathBuf),
#[error("Could not read thumbnail from ID3 tag in `{0}`:\n\n{1}")]
Id3(PathBuf, id3::Error),
#[error("Could not read thumbnail image in `{0}`:\n\n{1}")]
Image(PathBuf, image::error::ImageError),
#[error("Filesystem error for `{0}`: `{1}`")]
Io(PathBuf, std::io::Error),
#[error("Could not read thumbnail from flac file in `{0}`:\n\n{1}")]
Metaflac(PathBuf, metaflac::Error),
#[error("Could not read thumbnail from mp4 file in `{0}`:\n\n{1}")]
Mp4aMeta(PathBuf, mp4ameta::Error),
#[error("This file format is not supported: {0}")]
UnsupportedFormat(&'static str),
}
#[derive(Debug, Hash)]
pub struct Options {
pub max_dimension: Option<u32>,

View file

@ -5,35 +5,8 @@ use serde::{Deserialize, Serialize};
use std::time::{SystemTime, UNIX_EPOCH};
use crate::app::settings::AuthSecret;
use crate::db::{self, DB};
#[derive(thiserror::Error, Debug)]
pub enum Error {
#[error(transparent)]
Database(#[from] sqlx::Error),
#[error(transparent)]
DatabaseConnection(#[from] db::Error),
#[error("Cannot use empty username")]
EmptyUsername,
#[error("Cannot use empty password")]
EmptyPassword,
#[error("Username does not exist")]
IncorrectUsername,
#[error("Password does not match username")]
IncorrectPassword,
#[error("Invalid auth token")]
InvalidAuthToken,
#[error("Incorrect authorization scope")]
IncorrectAuthorizationScope,
#[error("Last.fm session key is missing")]
MissingLastFMSessionKey,
#[error("Failed to hash password")]
PasswordHashing,
#[error("Failed to encode authorization token")]
AuthorizationTokenEncoding,
#[error("Failed to encode Branca token")]
BrancaTokenEncoding,
}
use crate::app::Error;
use crate::db::DB;
#[derive(Debug)]
pub struct User {

View file

@ -4,17 +4,8 @@ use serde::{Deserialize, Serialize};
use sqlx::{Acquire, QueryBuilder, Sqlite};
use std::path::{self, Path, PathBuf};
use crate::db::{self, DB};
#[derive(thiserror::Error, Debug)]
pub enum Error {
#[error("The following virtual path could not be mapped to a real path: `{0}`")]
CouldNotMapToRealPath(PathBuf),
#[error(transparent)]
DatabaseConnection(#[from] db::Error),
#[error(transparent)]
Database(#[from] sqlx::Error),
}
use crate::app::Error;
use crate::db::DB;
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)]
pub struct MountDir {

View file

@ -1,4 +1,4 @@
use std::path::{Path, PathBuf};
use std::path::Path;
use sqlx::{
migrate::Migrator,
@ -7,19 +7,9 @@ use sqlx::{
Sqlite,
};
static MIGRATOR: Migrator = sqlx::migrate!("src/db");
use crate::app::Error;
#[derive(thiserror::Error, Debug)]
pub enum Error {
#[error("Could not initialize database connection pool")]
ConnectionPoolBuild,
#[error("Could not acquire database connection from pool")]
ConnectionPool,
#[error("Filesystem error for `{0}`: `{1}`")]
Io(PathBuf, std::io::Error),
#[error("Could not apply database migrations: {0}")]
Migration(sqlx::migrate::MigrateError),
}
static MIGRATOR: Migrator = sqlx::migrate!("src/db");
#[derive(Clone)]
pub struct DB {

View file

@ -39,13 +39,11 @@ impl IntoResponse for APIError {
APIError::OwnAdminPrivilegeRemoval => StatusCode::CONFLICT,
APIError::PasswordHashing => StatusCode::INTERNAL_SERVER_ERROR,
APIError::PlaylistNotFound => StatusCode::NOT_FOUND,
APIError::Settings(_) => StatusCode::INTERNAL_SERVER_ERROR,
APIError::ThumbnailFlacDecoding(_, _) => StatusCode::INTERNAL_SERVER_ERROR,
APIError::ThumbnailFileIOError => StatusCode::NOT_FOUND,
APIError::ThumbnailId3Decoding(_, _) => StatusCode::INTERNAL_SERVER_ERROR,
APIError::ThumbnailImageDecoding(_, _) => StatusCode::INTERNAL_SERVER_ERROR,
APIError::ThumbnailMp4Decoding(_, _) => StatusCode::INTERNAL_SERVER_ERROR,
APIError::TomlDeserialization(_) => StatusCode::INTERNAL_SERVER_ERROR,
APIError::UnsupportedThumbnailFormat(_) => StatusCode::INTERNAL_SERVER_ERROR,
APIError::UserNotFound => StatusCode::NOT_FOUND,
APIError::VFSPathNotFound => StatusCode::NOT_FOUND,

View file

@ -1,8 +1,7 @@
use std::path::PathBuf;
use thiserror::Error;
use crate::app::{config, ddns, index, lastfm, playlist, settings, thumbnail, user, vfs};
use crate::db;
use crate::app;
#[derive(Error, Debug)]
pub enum APIError {
@ -66,8 +65,6 @@ pub enum APIError {
PasswordHashing,
#[error("Playlist not found")]
PlaylistNotFound,
#[error("Settings error:\n\n{0}")]
Settings(settings::Error),
#[error("Could not decode thumbnail from flac file `{0}`:\n\n{1}")]
ThumbnailFlacDecoding(PathBuf, metaflac::Error),
#[error("Thumbnail file could not be opened")]
@ -78,8 +75,6 @@ pub enum APIError {
ThumbnailImageDecoding(PathBuf, image::error::ImageError),
#[error("Could not decode thumbnail from mp4 file `{0}`:\n\n{1}")]
ThumbnailMp4Decoding(PathBuf, mp4ameta::Error),
#[error("Toml deserialization error:\n\n{0}")]
TomlDeserialization(toml::de::Error),
#[error("Unsupported thumbnail format: `{0}`")]
UnsupportedThumbnailFormat(&'static str),
#[error("User not found")]
@ -88,135 +83,63 @@ pub enum APIError {
VFSPathNotFound,
}
impl From<index::Error> for APIError {
fn from(error: index::Error) -> APIError {
impl From<app::Error> for APIError {
fn from(error: app::Error) -> APIError {
match error {
index::Error::DirectoryNotFound(d) => APIError::DirectoryNotFound(d),
index::Error::ArtistNotFound => APIError::ArtistNotFound,
index::Error::AlbumNotFound => APIError::AlbumNotFound,
index::Error::SongNotFound => APIError::SongNotFound,
index::Error::Database(e) => APIError::Database(e),
index::Error::DatabaseConnection(e) => e.into(),
index::Error::Vfs(e) => e.into(),
index::Error::IndexDeserializationError => APIError::Internal,
index::Error::IndexSerializationError => APIError::Internal,
index::Error::ThreadPoolBuilder(_) => APIError::Internal,
index::Error::ThreadJoining(_) => APIError::Internal,
}
}
}
app::Error::ThreadPoolBuilder(_) => APIError::Internal,
app::Error::ThreadJoining(_) => APIError::Internal,
impl From<config::Error> for APIError {
fn from(error: config::Error) -> APIError {
match error {
config::Error::Ddns(e) => e.into(),
config::Error::Io(p, e) => APIError::Io(p, e),
config::Error::Settings(e) => e.into(),
config::Error::Toml(e) => APIError::TomlDeserialization(e),
config::Error::User(e) => e.into(),
config::Error::Vfs(e) => e.into(),
}
}
}
app::Error::Io(p, e) => APIError::Io(p, e),
app::Error::Ape(_) => APIError::Internal,
app::Error::Id3(p, e) => APIError::ThumbnailId3Decoding(p, e),
app::Error::Metaflac(p, e) => APIError::ThumbnailFlacDecoding(p, e),
app::Error::Mp4aMeta(p, e) => APIError::ThumbnailMp4Decoding(p, e),
app::Error::Opus(_) => APIError::Internal,
app::Error::Vorbis(_) => APIError::Internal,
app::Error::VorbisCommentNotFoundInFlacFile => APIError::Internal,
app::Error::Image(p, e) => APIError::ThumbnailImageDecoding(p, e),
app::Error::UnsupportedFormat(f) => APIError::UnsupportedThumbnailFormat(f),
impl From<playlist::Error> for APIError {
fn from(error: playlist::Error) -> APIError {
match error {
playlist::Error::Database(e) => APIError::Database(e),
playlist::Error::DatabaseConnection(e) => e.into(),
playlist::Error::PlaylistNotFound => APIError::PlaylistNotFound,
playlist::Error::UserNotFound => APIError::UserNotFound,
playlist::Error::Vfs(e) => e.into(),
}
}
}
app::Error::Database(e) => APIError::Database(e),
app::Error::ConnectionPoolBuild => APIError::Internal,
app::Error::ConnectionPool => APIError::Internal,
app::Error::Migration(_) => APIError::Internal,
impl From<settings::Error> for APIError {
fn from(error: settings::Error) -> APIError {
match error {
settings::Error::AuthenticationSecretNotFound => APIError::Settings(error),
settings::Error::DatabaseConnection(e) => e.into(),
settings::Error::AuthenticationSecretInvalid => APIError::Settings(error),
settings::Error::MiscSettingsNotFound => APIError::Settings(error),
settings::Error::IndexAlbumArtPatternInvalid => APIError::Settings(error),
settings::Error::Database(e) => APIError::Database(e),
}
}
}
app::Error::UpdateQueryFailed(s) => APIError::DdnsUpdateQueryFailed(s),
app::Error::UpdateQueryTransport => APIError::DdnsUpdateQueryFailed(0),
impl From<user::Error> for APIError {
fn from(error: user::Error) -> APIError {
match error {
user::Error::AuthorizationTokenEncoding => APIError::AuthorizationTokenEncoding,
user::Error::BrancaTokenEncoding => APIError::BrancaTokenEncoding,
user::Error::Database(e) => APIError::Database(e),
user::Error::DatabaseConnection(e) => e.into(),
user::Error::EmptyPassword => APIError::EmptyPassword,
user::Error::EmptyUsername => APIError::EmptyUsername,
user::Error::IncorrectAuthorizationScope => APIError::IncorrectCredentials,
user::Error::IncorrectPassword => APIError::IncorrectCredentials,
user::Error::IncorrectUsername => APIError::IncorrectCredentials,
user::Error::InvalidAuthToken => APIError::IncorrectCredentials,
user::Error::MissingLastFMSessionKey => APIError::IncorrectCredentials,
user::Error::PasswordHashing => APIError::PasswordHashing,
}
}
}
app::Error::AuthenticationSecretNotFound => APIError::Internal,
app::Error::AuthenticationSecretInvalid => APIError::Internal,
app::Error::MiscSettingsNotFound => APIError::Internal,
app::Error::IndexAlbumArtPatternInvalid => APIError::Internal,
impl From<vfs::Error> for APIError {
fn from(error: vfs::Error) -> APIError {
match error {
vfs::Error::CouldNotMapToRealPath(_) => APIError::VFSPathNotFound,
vfs::Error::Database(e) => APIError::Database(e),
vfs::Error::DatabaseConnection(e) => e.into(),
}
}
}
app::Error::Toml(_) => APIError::Internal,
app::Error::IndexDeserializationError => APIError::Internal,
app::Error::IndexSerializationError => APIError::Internal,
impl From<ddns::Error> for APIError {
fn from(error: ddns::Error) -> APIError {
match error {
ddns::Error::Database(e) => APIError::Database(e),
ddns::Error::DatabaseConnection(e) => e.into(),
ddns::Error::UpdateQueryFailed(s) => APIError::DdnsUpdateQueryFailed(s),
ddns::Error::UpdateQueryTransport => APIError::DdnsUpdateQueryFailed(0),
}
}
}
app::Error::CouldNotMapToRealPath(_) => APIError::VFSPathNotFound,
app::Error::UserNotFound => APIError::UserNotFound,
app::Error::DirectoryNotFound(d) => APIError::DirectoryNotFound(d),
app::Error::ArtistNotFound => APIError::ArtistNotFound,
app::Error::AlbumNotFound => APIError::AlbumNotFound,
app::Error::SongNotFound => APIError::SongNotFound,
app::Error::PlaylistNotFound => APIError::PlaylistNotFound,
app::Error::EmbeddedArtworkNotFound(_) => APIError::EmbeddedArtworkNotFound,
impl From<db::Error> for APIError {
fn from(error: db::Error) -> APIError {
match error {
db::Error::ConnectionPoolBuild => APIError::Internal,
db::Error::ConnectionPool => APIError::Internal,
db::Error::Io(p, e) => APIError::Io(p, e),
db::Error::Migration(_) => APIError::Internal,
}
}
}
app::Error::EmptyUsername => APIError::EmptyUsername,
app::Error::EmptyPassword => APIError::EmptyPassword,
app::Error::IncorrectUsername => APIError::IncorrectCredentials,
app::Error::IncorrectPassword => APIError::IncorrectCredentials,
app::Error::InvalidAuthToken => APIError::IncorrectCredentials,
app::Error::IncorrectAuthorizationScope => APIError::IncorrectCredentials,
app::Error::MissingLastFMSessionKey => APIError::IncorrectCredentials,
app::Error::PasswordHashing => APIError::PasswordHashing,
app::Error::AuthorizationTokenEncoding => APIError::AuthorizationTokenEncoding,
app::Error::BrancaTokenEncoding => APIError::BrancaTokenEncoding,
impl From<lastfm::Error> for APIError {
fn from(error: lastfm::Error) -> APIError {
match error {
lastfm::Error::ScrobblerAuthentication(e) => APIError::LastFMScrobblerAuthentication(e),
lastfm::Error::Scrobble(e) => APIError::LastFMScrobble(e),
lastfm::Error::NowPlaying(e) => APIError::LastFMNowPlaying(e),
lastfm::Error::Query(e) => e.into(),
lastfm::Error::User(e) => e.into(),
}
}
}
impl From<thumbnail::Error> for APIError {
fn from(error: thumbnail::Error) -> APIError {
match error {
thumbnail::Error::EmbeddedArtworkNotFound(_) => APIError::EmbeddedArtworkNotFound,
thumbnail::Error::Id3(p, e) => APIError::ThumbnailId3Decoding(p, e),
thumbnail::Error::Image(p, e) => APIError::ThumbnailImageDecoding(p, e),
thumbnail::Error::Io(p, e) => APIError::Io(p, e),
thumbnail::Error::Metaflac(p, e) => APIError::ThumbnailFlacDecoding(p, e),
thumbnail::Error::Mp4aMeta(p, e) => APIError::ThumbnailMp4Decoding(p, e),
thumbnail::Error::UnsupportedFormat(f) => APIError::UnsupportedThumbnailFormat(f),
app::Error::ScrobblerAuthentication(e) => APIError::LastFMScrobblerAuthentication(e),
app::Error::Scrobble(e) => APIError::LastFMScrobble(e),
app::Error::NowPlaying(e) => APIError::LastFMNowPlaying(e),
}
}
}