1
0
mirror of https://github.com/actix/actix-extras.git synced 2024-11-23 23:51:06 +01:00
actix-extras/actix-identity/src/error.rs
Joseph McCormick 1ed893a08c
Feature: Add IdentityError to actix-identity crate. (#296)
* Add IdentityError to actix-identity crate.

In order to let crates in the actix web ecosystem interact correctly
with `actix_web::Error`, this commit introduces its own error type,
replacing the previous usage of `anyhow::Error`.

* Mend some clippy warnings on IdentityError.

* Split identity error into more granular versions.

- `MissingIdentityError` occurs whenever we attempt to gather
  information about an identity from a session, and fail.
- `LoginError` occurs whenever we attempt to login via an identity, and
  fail.

* Feedback for identity error implementation.

- `IdentityError` -> `GetIdentityError`
- Move error messages into Display impl where appropriate
- Split `id` and `get_identity` errors into two types
- Implement `source` on custom errors

* Expand identity error types with struct markers.

In order to get a little more future compatibility and reduce
abstraction leaking, this commit introduces some contextual structs to
our identity errors package.

* Improve doc message for SessionExpiryError.

Co-authored-by: Luca Palmieri <20745048+LukeMathWalker@users.noreply.github.com>

* Improve identity error docs and messaging.

Co-authored-by: Luca Palmieri <20745048+LukeMathWalker@users.noreply.github.com>

* Expand LostIdentityError with placeholder.

Adds a placeholder unit struct to the LostIdentityError variant of
GetIdentityError, which should let us expand on that variant with extra
context later if we like.

* Add From coercion for LostIdentityError.

Improve the ergonomics of using the LostIdentityError unit struct.

* Update Cargo.toml

* Update CHANGES.md

* expose identity error module

* fix error impl

Co-authored-by: Luca Palmieri <20745048+LukeMathWalker@users.noreply.github.com>
Co-authored-by: Rob Ede <robjtede@icloud.com>
2023-01-07 02:05:12 +00:00

157 lines
4.3 KiB
Rust

//! Failure modes of identity operations.
use std::fmt;
use actix_session::{SessionGetError, SessionInsertError};
use actix_web::{cookie::time::error::ComponentRange, http::StatusCode, ResponseError};
/// Error that can occur during login attempts.
#[derive(Debug)]
pub struct LoginError(SessionInsertError);
impl fmt::Display for LoginError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}
impl std::error::Error for LoginError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
Some(&self.0)
}
}
impl ResponseError for LoginError {
fn status_code(&self) -> StatusCode {
StatusCode::UNAUTHORIZED
}
}
impl From<SessionInsertError> for LoginError {
fn from(error: SessionInsertError) -> Self {
Self(error)
}
}
/// Error encountered when working with a session that has expired.
#[derive(Debug)]
pub struct SessionExpiryError(ComponentRange);
impl fmt::Display for SessionExpiryError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("The given session has expired and is no longer valid")
}
}
impl std::error::Error for SessionExpiryError {}
/// The identity information has been lost.
///
/// Seeing this error in user code indicates a bug in actix-identity.
#[derive(Debug)]
#[non_exhaustive]
pub struct LostIdentityError;
impl fmt::Display for LostIdentityError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(
"The identity information in the current session has disappeared \
after having been successfully validated. This is likely to be a bug.",
)
}
}
impl std::error::Error for LostIdentityError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
Some(self)
}
}
/// There is no identity information attached to the current session.
#[derive(Debug)]
#[non_exhaustive]
pub struct MissingIdentityError;
impl fmt::Display for MissingIdentityError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("There is no identity information attached to the current session.")
}
}
impl std::error::Error for MissingIdentityError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
Some(self)
}
}
/// Errors that can occur while retrieving an identity.
#[derive(Debug)]
#[non_exhaustive]
pub enum GetIdentityError {
/// The session has expired.
SessionExpiryError(SessionExpiryError),
/// No identity is found in a session.
MissingIdentityError(MissingIdentityError),
/// Failed to accessing the session store.
SessionGetError(SessionGetError),
/// Identity info was lost after being validated.
///
/// Seeing this error indicates a bug in actix-identity.
LostIdentityError(LostIdentityError),
}
impl fmt::Display for GetIdentityError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::SessionExpiryError(err) => write!(f, "{err}"),
Self::MissingIdentityError(err) => write!(f, "{err}"),
Self::SessionGetError(err) => write!(f, "{err}"),
Self::LostIdentityError(err) => write!(f, "{err}"),
}
}
}
impl std::error::Error for GetIdentityError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Self::SessionExpiryError(err) => Some(err),
Self::MissingIdentityError(err) => Some(err),
Self::SessionGetError(err) => Some(err),
Self::LostIdentityError(err) => Some(err),
}
}
}
impl ResponseError for GetIdentityError {
fn status_code(&self) -> StatusCode {
StatusCode::UNAUTHORIZED
}
}
impl From<LostIdentityError> for GetIdentityError {
fn from(error: LostIdentityError) -> Self {
Self::LostIdentityError(error)
}
}
impl From<MissingIdentityError> for GetIdentityError {
fn from(error: MissingIdentityError) -> Self {
Self::MissingIdentityError(error)
}
}
impl From<ComponentRange> for GetIdentityError {
fn from(error: ComponentRange) -> Self {
Self::SessionExpiryError(SessionExpiryError(error))
}
}
impl From<SessionGetError> for GetIdentityError {
fn from(source: SessionGetError) -> Self {
Self::SessionGetError(source)
}
}