mirror of
https://github.com/librespot-org/librespot.git
synced 2024-12-18 17:11:53 +00:00
Replace error_chain by thiserror
This commit is contained in:
parent
45f42acb82
commit
27f308b82f
6 changed files with 63 additions and 55 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -1435,7 +1435,6 @@ dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"cfg-if 1.0.0",
|
"cfg-if 1.0.0",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
"error-chain",
|
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-sink",
|
"futures-sink",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
|
@ -1455,6 +1454,7 @@ dependencies = [
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"sha-1 0.9.4",
|
"sha-1 0.9.4",
|
||||||
"shannon",
|
"shannon",
|
||||||
|
"thiserror",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-stream",
|
"tokio-stream",
|
||||||
"tokio-util",
|
"tokio-util",
|
||||||
|
|
|
@ -18,7 +18,6 @@ base64 = "0.13"
|
||||||
byteorder = "1.4"
|
byteorder = "1.4"
|
||||||
bytes = "1.0"
|
bytes = "1.0"
|
||||||
cfg-if = "1"
|
cfg-if = "1"
|
||||||
error-chain = { version = "0.12", default-features = false }
|
|
||||||
futures-core = { version = "0.3", default-features = false }
|
futures-core = { version = "0.3", default-features = false }
|
||||||
futures-sink = { version = "0.3", default-features = false }
|
futures-sink = { version = "0.3", default-features = false }
|
||||||
futures-util = { version = "0.3", default-features = false, features = ["alloc", "bilock", "unstable", "sink"] }
|
futures-util = { version = "0.3", default-features = false, features = ["alloc", "bilock", "unstable", "sink"] }
|
||||||
|
@ -37,6 +36,7 @@ serde = { version = "1.0", features = ["derive"] }
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
sha-1 = "0.9"
|
sha-1 = "0.9"
|
||||||
shannon = "0.2.0"
|
shannon = "0.2.0"
|
||||||
|
thiserror = "1"
|
||||||
tokio = { version = "1.0", features = ["io-util", "net", "rt", "sync"] }
|
tokio = { version = "1.0", features = ["io-util", "net", "rt", "sync"] }
|
||||||
tokio-stream = "0.1"
|
tokio-stream = "0.1"
|
||||||
tokio-util = { version = "0.6", features = ["codec"] }
|
tokio-util = { version = "0.6", features = ["codec"] }
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
use std::io::{self, Read};
|
use std::io::{self, Read};
|
||||||
use std::ops::FnOnce;
|
|
||||||
|
|
||||||
use aes::Aes192;
|
use aes::Aes192;
|
||||||
use byteorder::{BigEndian, ByteOrder};
|
use byteorder::{BigEndian, ByteOrder};
|
||||||
|
@ -10,7 +9,6 @@ use serde::{Deserialize, Serialize};
|
||||||
use sha1::{Digest, Sha1};
|
use sha1::{Digest, Sha1};
|
||||||
|
|
||||||
use crate::protocol::authentication::AuthenticationType;
|
use crate::protocol::authentication::AuthenticationType;
|
||||||
use crate::protocol::keyexchange::{APLoginFailed, ErrorCode};
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct Credentials {
|
pub struct Credentials {
|
||||||
|
@ -144,37 +142,3 @@ where
|
||||||
let v: String = serde::Deserialize::deserialize(de)?;
|
let v: String = serde::Deserialize::deserialize(de)?;
|
||||||
base64::decode(&v).map_err(|e| serde::de::Error::custom(e.to_string()))
|
base64::decode(&v).map_err(|e| serde::de::Error::custom(e.to_string()))
|
||||||
}
|
}
|
||||||
|
|
||||||
error_chain! {
|
|
||||||
types {
|
|
||||||
AuthenticationError, AuthenticationErrorKind, AuthenticationResultExt, AuthenticationResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreign_links {
|
|
||||||
Io(::std::io::Error);
|
|
||||||
}
|
|
||||||
|
|
||||||
errors {
|
|
||||||
BadCredentials {
|
|
||||||
description("Bad credentials")
|
|
||||||
display("Authentication failed with error: Bad credentials")
|
|
||||||
}
|
|
||||||
PremiumAccountRequired {
|
|
||||||
description("Premium account required")
|
|
||||||
display("Authentication failed with error: Premium account required")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<APLoginFailed> for AuthenticationError {
|
|
||||||
fn from(login_failure: APLoginFailed) -> Self {
|
|
||||||
let error_code = login_failure.get_error_code();
|
|
||||||
match error_code {
|
|
||||||
ErrorCode::BadCredentials => Self::from_kind(AuthenticationErrorKind::BadCredentials),
|
|
||||||
ErrorCode::PremiumAccountRequired => {
|
|
||||||
Self::from_kind(AuthenticationErrorKind::PremiumAccountRequired)
|
|
||||||
}
|
|
||||||
_ => format!("Authentication failed with error: {:?}", error_code).into(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -4,21 +4,60 @@ mod handshake;
|
||||||
pub use self::codec::APCodec;
|
pub use self::codec::APCodec;
|
||||||
pub use self::handshake::handshake;
|
pub use self::handshake::handshake;
|
||||||
|
|
||||||
use futures_util::{SinkExt, StreamExt};
|
use std::io::{self, ErrorKind};
|
||||||
use protobuf::{self, Message};
|
|
||||||
use std::io;
|
|
||||||
use std::net::ToSocketAddrs;
|
use std::net::ToSocketAddrs;
|
||||||
|
|
||||||
|
use futures_util::{SinkExt, StreamExt};
|
||||||
|
use protobuf::{self, Message, ProtobufError};
|
||||||
|
use thiserror::Error;
|
||||||
use tokio::net::TcpStream;
|
use tokio::net::TcpStream;
|
||||||
use tokio_util::codec::Framed;
|
use tokio_util::codec::Framed;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
use crate::authentication::{AuthenticationError, Credentials};
|
use crate::authentication::Credentials;
|
||||||
|
use crate::protocol::keyexchange::{APLoginFailed, ErrorCode};
|
||||||
|
use crate::proxytunnel;
|
||||||
use crate::version;
|
use crate::version;
|
||||||
|
|
||||||
use crate::proxytunnel;
|
|
||||||
|
|
||||||
pub type Transport = Framed<TcpStream, APCodec>;
|
pub type Transport = Framed<TcpStream, APCodec>;
|
||||||
|
|
||||||
|
fn login_error_message(code: &ErrorCode) -> &'static str {
|
||||||
|
pub use ErrorCode::*;
|
||||||
|
match code {
|
||||||
|
ProtocolError => "Protocol error",
|
||||||
|
TryAnotherAP => "Try another AP",
|
||||||
|
BadConnectionId => "Bad connection id",
|
||||||
|
TravelRestriction => "Travel restriction",
|
||||||
|
PremiumAccountRequired => "Premium account required",
|
||||||
|
BadCredentials => "Bad credentials",
|
||||||
|
CouldNotValidateCredentials => "Could not validate credentials",
|
||||||
|
AccountExists => "Account exists",
|
||||||
|
ExtraVerificationRequired => "Extra verification required",
|
||||||
|
InvalidAppKey => "Invalid app key",
|
||||||
|
ApplicationBanned => "Application banned",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Error)]
|
||||||
|
pub enum AuthenticationError {
|
||||||
|
#[error("Login failed with reason: {}", login_error_message(.0))]
|
||||||
|
LoginFailed(ErrorCode),
|
||||||
|
#[error("Authentication failed: {0}")]
|
||||||
|
IoError(#[from] io::Error),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<ProtobufError> for AuthenticationError {
|
||||||
|
fn from(e: ProtobufError) -> Self {
|
||||||
|
io::Error::new(ErrorKind::InvalidData, e).into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<APLoginFailed> for AuthenticationError {
|
||||||
|
fn from(login_failure: APLoginFailed) -> Self {
|
||||||
|
Self::LoginFailed(login_failure.get_error_code())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn connect(addr: String, proxy: &Option<Url>) -> io::Result<Transport> {
|
pub async fn connect(addr: String, proxy: &Option<Url>) -> io::Result<Transport> {
|
||||||
let socket = if let Some(proxy) = proxy {
|
let socket = if let Some(proxy) = proxy {
|
||||||
info!("Using proxy \"{}\"", proxy);
|
info!("Using proxy \"{}\"", proxy);
|
||||||
|
@ -66,7 +105,6 @@ pub async fn authenticate(
|
||||||
device_id: &str,
|
device_id: &str,
|
||||||
) -> Result<Credentials, AuthenticationError> {
|
) -> Result<Credentials, AuthenticationError> {
|
||||||
use crate::protocol::authentication::{APWelcome, ClientResponseEncrypted, CpuFamily, Os};
|
use crate::protocol::authentication::{APWelcome, ClientResponseEncrypted, CpuFamily, Os};
|
||||||
use crate::protocol::keyexchange::APLoginFailed;
|
|
||||||
|
|
||||||
let mut packet = ClientResponseEncrypted::new();
|
let mut packet = ClientResponseEncrypted::new();
|
||||||
packet
|
packet
|
||||||
|
@ -101,7 +139,7 @@ pub async fn authenticate(
|
||||||
let (cmd, data) = transport.next().await.expect("EOF")?;
|
let (cmd, data) = transport.next().await.expect("EOF")?;
|
||||||
match cmd {
|
match cmd {
|
||||||
0xac => {
|
0xac => {
|
||||||
let welcome_data: APWelcome = protobuf::parse_from_bytes(data.as_ref()).unwrap();
|
let welcome_data: APWelcome = protobuf::parse_from_bytes(data.as_ref())?;
|
||||||
|
|
||||||
let reusable_credentials = Credentials {
|
let reusable_credentials = Credentials {
|
||||||
username: welcome_data.get_canonical_username().to_owned(),
|
username: welcome_data.get_canonical_username().to_owned(),
|
||||||
|
@ -111,12 +149,13 @@ pub async fn authenticate(
|
||||||
|
|
||||||
Ok(reusable_credentials)
|
Ok(reusable_credentials)
|
||||||
}
|
}
|
||||||
|
|
||||||
0xad => {
|
0xad => {
|
||||||
let error_data: APLoginFailed = protobuf::parse_from_bytes(data.as_ref()).unwrap();
|
let error_data: APLoginFailed = protobuf::parse_from_bytes(data.as_ref())?;
|
||||||
Err(error_data.into())
|
Err(error_data.into())
|
||||||
}
|
}
|
||||||
|
_ => {
|
||||||
_ => panic!("Unexpected packet {:?}", cmd),
|
let msg = format!("Received invalid packet: {}", cmd);
|
||||||
|
Err(io::Error::new(ErrorKind::InvalidData, msg).into())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,8 +4,6 @@
|
||||||
extern crate log;
|
extern crate log;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate cfg_if;
|
extern crate cfg_if;
|
||||||
#[macro_use]
|
|
||||||
extern crate error_chain;
|
|
||||||
|
|
||||||
use librespot_protocol as protocol;
|
use librespot_protocol as protocol;
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ use bytes::Bytes;
|
||||||
use futures_core::TryStream;
|
use futures_core::TryStream;
|
||||||
use futures_util::{FutureExt, StreamExt, TryStreamExt};
|
use futures_util::{FutureExt, StreamExt, TryStreamExt};
|
||||||
use once_cell::sync::OnceCell;
|
use once_cell::sync::OnceCell;
|
||||||
|
use thiserror::Error;
|
||||||
use tokio::sync::mpsc;
|
use tokio::sync::mpsc;
|
||||||
use tokio_stream::wrappers::UnboundedReceiverStream;
|
use tokio_stream::wrappers::UnboundedReceiverStream;
|
||||||
|
|
||||||
|
@ -21,10 +22,16 @@ use crate::authentication::Credentials;
|
||||||
use crate::cache::Cache;
|
use crate::cache::Cache;
|
||||||
use crate::channel::ChannelManager;
|
use crate::channel::ChannelManager;
|
||||||
use crate::config::SessionConfig;
|
use crate::config::SessionConfig;
|
||||||
use crate::connection;
|
use crate::connection::{self, AuthenticationError};
|
||||||
use crate::mercury::MercuryManager;
|
use crate::mercury::MercuryManager;
|
||||||
|
|
||||||
pub use crate::authentication::{AuthenticationError, AuthenticationErrorKind};
|
#[derive(Debug, Error)]
|
||||||
|
pub enum SessionError {
|
||||||
|
#[error(transparent)]
|
||||||
|
AuthenticationError(#[from] AuthenticationError),
|
||||||
|
#[error("Cannot create session: {0}")]
|
||||||
|
IoError(#[from] io::Error),
|
||||||
|
}
|
||||||
|
|
||||||
struct SessionData {
|
struct SessionData {
|
||||||
country: String,
|
country: String,
|
||||||
|
@ -59,7 +66,7 @@ impl Session {
|
||||||
config: SessionConfig,
|
config: SessionConfig,
|
||||||
credentials: Credentials,
|
credentials: Credentials,
|
||||||
cache: Option<Cache>,
|
cache: Option<Cache>,
|
||||||
) -> Result<Session, AuthenticationError> {
|
) -> Result<Session, SessionError> {
|
||||||
let ap = apresolve_or_fallback(&config.proxy, &config.ap_port).await;
|
let ap = apresolve_or_fallback(&config.proxy, &config.ap_port).await;
|
||||||
|
|
||||||
info!("Connecting to AP \"{}\"", ap);
|
info!("Connecting to AP \"{}\"", ap);
|
||||||
|
|
Loading…
Reference in a new issue