forked from 2sys/shoutdotdev
remove common suffix from AppError enum members
This commit is contained in:
parent
1f08b5a590
commit
2c15cdfd11
7 changed files with 31 additions and 36 deletions
|
@ -8,18 +8,16 @@ use validator::ValidationErrors;
|
|||
#[derive(Debug)]
|
||||
pub enum AppError {
|
||||
InternalServerError(anyhow::Error),
|
||||
ForbiddenError(String),
|
||||
NotFoundError(String),
|
||||
BadRequestError(String),
|
||||
TooManyRequestsError(String),
|
||||
Forbidden(String),
|
||||
NotFound(String),
|
||||
BadRequest(String),
|
||||
TooManyRequests(String),
|
||||
}
|
||||
|
||||
impl AppError {
|
||||
pub fn from_validation_errors(errs: ValidationErrors) -> Self {
|
||||
// TODO: customize validation errors formatting
|
||||
Self::BadRequestError(
|
||||
serde_json::to_string(&errs).unwrap_or("validation error".to_string()),
|
||||
)
|
||||
Self::BadRequest(serde_json::to_string(&errs).unwrap_or("validation error".to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -30,21 +28,21 @@ impl IntoResponse for AppError {
|
|||
tracing::error!("Application error: {:?}", err);
|
||||
(StatusCode::INTERNAL_SERVER_ERROR, "Something went wrong").into_response()
|
||||
}
|
||||
Self::ForbiddenError(client_message) => {
|
||||
Self::Forbidden(client_message) => {
|
||||
tracing::info!("Forbidden: {}", client_message);
|
||||
(StatusCode::FORBIDDEN, client_message).into_response()
|
||||
}
|
||||
Self::NotFoundError(client_message) => {
|
||||
Self::NotFound(client_message) => {
|
||||
tracing::info!("Not found: {}", client_message);
|
||||
(StatusCode::NOT_FOUND, client_message).into_response()
|
||||
}
|
||||
Self::TooManyRequestsError(client_message) => {
|
||||
Self::TooManyRequests(client_message) => {
|
||||
// Debug level so that if this is from a runaway loop, it won't
|
||||
// overwhelm server logs
|
||||
tracing::debug!("Too many requests: {}", client_message);
|
||||
(StatusCode::TOO_MANY_REQUESTS, client_message).into_response()
|
||||
}
|
||||
Self::BadRequestError(client_message) => {
|
||||
Self::BadRequest(client_message) => {
|
||||
tracing::info!("Bad user input: {}", client_message);
|
||||
(StatusCode::BAD_REQUEST, client_message).into_response()
|
||||
}
|
||||
|
@ -66,16 +64,16 @@ impl Display for AppError {
|
|||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
AppError::InternalServerError(inner) => inner.fmt(f),
|
||||
AppError::ForbiddenError(client_message) => {
|
||||
AppError::Forbidden(client_message) => {
|
||||
write!(f, "ForbiddenError: {}", client_message)
|
||||
}
|
||||
AppError::NotFoundError(client_message) => {
|
||||
AppError::NotFound(client_message) => {
|
||||
write!(f, "NotFoundError: {}", client_message)
|
||||
}
|
||||
AppError::BadRequestError(client_message) => {
|
||||
AppError::BadRequest(client_message) => {
|
||||
write!(f, "BadRequestError: {}", client_message)
|
||||
}
|
||||
AppError::TooManyRequestsError(client_message) => {
|
||||
AppError::TooManyRequests(client_message) => {
|
||||
write!(f, "TooManyRequestsError: {}", client_message)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -167,7 +167,7 @@ async fn callback(
|
|||
})?;
|
||||
if session_csrf_token != query.state {
|
||||
tracing::debug!("oauth csrf tokens did not match");
|
||||
return Err(AppError::ForbiddenError(
|
||||
return Err(AppError::Forbidden(
|
||||
"OAuth CSRF tokens do not match.".to_string(),
|
||||
));
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ fn get_channel_by_params<'a>(
|
|||
.filter(Channel::with_team(team_id))
|
||||
.first(conn)
|
||||
{
|
||||
diesel::QueryResult::Err(diesel::result::Error::NotFound) => Err(AppError::NotFoundError(
|
||||
diesel::QueryResult::Err(diesel::result::Error::NotFound) => Err(AppError::NotFound(
|
||||
"Channel with that team and ID not found.".to_string(),
|
||||
)),
|
||||
diesel::QueryResult::Err(err) => Err(err.into()),
|
||||
|
@ -153,7 +153,7 @@ async fn post_new_channel(
|
|||
.await
|
||||
.unwrap()?,
|
||||
_ => {
|
||||
return Err(AppError::BadRequestError(
|
||||
return Err(AppError::BadRequest(
|
||||
"Channel type not recognized.".to_string(),
|
||||
));
|
||||
}
|
||||
|
@ -189,7 +189,7 @@ async fn channel_page(
|
|||
.unwrap()?
|
||||
{
|
||||
None => {
|
||||
return Err(AppError::NotFoundError(
|
||||
return Err(AppError::NotFound(
|
||||
"Channel with that team and ID not found".to_string(),
|
||||
));
|
||||
}
|
||||
|
@ -272,7 +272,7 @@ async fn update_channel(
|
|||
.context("Failed to load Channel while updating.")?
|
||||
};
|
||||
if updated_rows != 1 {
|
||||
return Err(AppError::NotFoundError(
|
||||
return Err(AppError::NotFound(
|
||||
"Channel with that team and ID not found".to_string(),
|
||||
));
|
||||
}
|
||||
|
@ -308,7 +308,7 @@ async fn update_channel_email_recipient(
|
|||
guards::require_team_membership(¤t_user, &team_id, &db_conn).await?;
|
||||
|
||||
if !is_permissible_email(&form_body.recipient) {
|
||||
return Err(AppError::BadRequestError(
|
||||
return Err(AppError::BadRequest(
|
||||
"Unable to validate email address format.".to_string(),
|
||||
));
|
||||
}
|
||||
|
@ -400,7 +400,7 @@ async fn verify_email(
|
|||
guards::require_team_membership(¤t_user, &team_id, &db_conn).await?;
|
||||
|
||||
if form_body.code.len() != VERIFICATION_CODE_LEN {
|
||||
return Err(AppError::BadRequestError(format!(
|
||||
return Err(AppError::BadRequest(format!(
|
||||
"Verification code must be {} characters long.",
|
||||
VERIFICATION_CODE_LEN
|
||||
)));
|
||||
|
@ -414,15 +414,13 @@ async fn verify_email(
|
|||
let channel = get_channel_by_params(conn, &team_id, &channel_id)?;
|
||||
let config: EmailBackendConfig = channel.backend_config.try_into()?;
|
||||
if config.verified {
|
||||
return Err(AppError::BadRequestError(
|
||||
return Err(AppError::BadRequest(
|
||||
"Channel's email address is already verified.".to_string(),
|
||||
));
|
||||
}
|
||||
const MAX_VERIFICATION_GUESSES: u32 = 100;
|
||||
if config.verification_code_guesses > MAX_VERIFICATION_GUESSES {
|
||||
return Err(AppError::BadRequestError(
|
||||
"Verification expired.".to_string(),
|
||||
));
|
||||
return Err(AppError::BadRequest("Verification expired.".to_string()));
|
||||
}
|
||||
let new_config = if config.verification_code == verification_code {
|
||||
EmailBackendConfig {
|
||||
|
|
|
@ -34,7 +34,7 @@ pub async fn require_team_membership(
|
|||
};
|
||||
match maybe_team {
|
||||
Some((team, _)) => Ok(team),
|
||||
None => Err(AppError::ForbiddenError(
|
||||
None => Err(AppError::Forbidden(
|
||||
"not a member of requested team".to_string(),
|
||||
)),
|
||||
}
|
||||
|
@ -50,6 +50,6 @@ pub async fn require_valid_csrf_token(
|
|||
if validate_csrf_token(db_conn, csrf_token, Some(current_user.id)).await? {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(AppError::ForbiddenError("invalid CSRF token".to_string()))
|
||||
Err(AppError::Forbidden("invalid CSRF token".to_string()))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -124,7 +124,7 @@ async fn project_page(
|
|||
.filter(Project::with_team(&team_id))
|
||||
.first(conn)
|
||||
{
|
||||
diesel::QueryResult::Err(diesel::NotFound) => Err(AppError::NotFoundError(
|
||||
diesel::QueryResult::Err(diesel::NotFound) => Err(AppError::NotFound(
|
||||
"Project with that team and ID not found.".to_string(),
|
||||
)),
|
||||
other => other
|
||||
|
@ -213,7 +213,7 @@ async fn update_enabled_channels(
|
|||
.filter(Project::with_team(&team_id))
|
||||
.first(conn)
|
||||
{
|
||||
diesel::QueryResult::Err(diesel::NotFound) => Err(AppError::NotFoundError(
|
||||
diesel::QueryResult::Err(diesel::NotFound) => Err(AppError::NotFound(
|
||||
"Project with that team and ID not found.".to_string(),
|
||||
)),
|
||||
other => other
|
||||
|
|
|
@ -139,7 +139,7 @@ async fn remove_api_key(
|
|||
"there should never be more than 1 API key with the same ID"
|
||||
);
|
||||
if n_deleted == 0 {
|
||||
Err(AppError::NotFoundError(
|
||||
Err(AppError::NotFound(
|
||||
"no API key with that ID and team found".to_owned(),
|
||||
))
|
||||
} else {
|
||||
|
|
|
@ -67,9 +67,8 @@ async fn say_get(
|
|||
query.validate().map_err(AppError::from_validation_errors)?;
|
||||
|
||||
let api_key = {
|
||||
let query_key = try_parse_as_uuid(&query.key).or(Err(AppError::ForbiddenError(
|
||||
"key not accepted".to_string(),
|
||||
)))?;
|
||||
let query_key = try_parse_as_uuid(&query.key)
|
||||
.or(Err(AppError::Forbidden("key not accepted".to_string())))?;
|
||||
db_conn
|
||||
.interact::<_, Result<ApiKey, AppError>>(move |conn| {
|
||||
update(api_keys::table.filter(ApiKey::with_id(&query_key)))
|
||||
|
@ -78,7 +77,7 @@ async fn say_get(
|
|||
.get_result(conn)
|
||||
.optional()
|
||||
.context("failed to get API key")?
|
||||
.ok_or(AppError::ForbiddenError("key not accepted.".to_string()))
|
||||
.ok_or(AppError::Forbidden("key not accepted.".to_string()))
|
||||
})
|
||||
.await
|
||||
.unwrap()?
|
||||
|
@ -146,7 +145,7 @@ async fn say_get(
|
|||
.unwrap()?
|
||||
.is_none()
|
||||
{
|
||||
return Err(AppError::TooManyRequestsError(
|
||||
return Err(AppError::TooManyRequests(
|
||||
"team rate limit exceeded".to_string(),
|
||||
));
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue