Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Return meaningful error message on Validation failure #20

Closed
c650 opened this issue Feb 10, 2021 · 10 comments · Fixed by #21
Closed

Return meaningful error message on Validation failure #20

c650 opened this issue Feb 10, 2021 · 10 comments · Fixed by #21

Comments

@c650
Copy link
Contributor

c650 commented Feb 10, 2021

Current behaviour is that we just return BAD_REQUEST... However, this is not enough because then we don't know which field(s) failed validation.

Current code:
https://github.com/rambler-digital-solutions/actix-web-validator/blob/master/src/error.rs#L51-L55

If we change this method we can return a list of errors, or at least the first one

@Roms1383
Copy link
Contributor

Roms1383 commented Mar 9, 2021

Well, I actually ran into the same issue but thought it was related to the way formatting is handled by serde_json.

In case it can be useful, here's how I solved it :
serde-rs/json#759 (comment)

I realize it doesn't belong to serde_json and could be added to this crate documentation, what do you think @c650 ?

@c650
Copy link
Contributor Author

c650 commented Mar 9, 2021

Wow @Roms1383 that's great. can I do this without implementing validator::Validate myself?

@Roms1383
Copy link
Contributor

Haven't found a better way so far 😅 @c650

@c650
Copy link
Contributor Author

c650 commented Mar 16, 2021

@Roms1383 that is why i made my own fork of this for now

@quantumsheep
Copy link

Any update on this?

@singulared
Copy link
Collaborator

singulared commented Jun 7, 2021

@quantumsheep @c650 I added some additional validation error information in 2.1
For JSON representation, you can use custom Config error_handler:

use actix_web::{web, App, HttpResponse, HttpServer, Responder, error};
use actix_web_validator::{QsQuery, QsQueryConfig, Error};
use serde::{Deserialize, Serialize};
use validator::Validate;

#[derive(Debug, Validate, Deserialize)]
pub struct Filter {
    #[validate(length(min = 3))]
    projects: Vec<i32>,
    #[validate(length(min = 2))]
    name: String,
}

async fn index(web::Path(path): web::Path<String>, query: QsQuery<Filter>) -> impl Responder {
    dbg!(query);
    HttpResponse::Ok().body(path)
}

#[derive(Serialize)]
pub struct ValidationErrorJsonPayload {
    pub message: String,
    pub fields: Vec<String>,
}

impl From<&validator::ValidationErrors> for ValidationErrorJsonPayload {
    fn from(error: &validator::ValidationErrors) -> Self {
        ValidationErrorJsonPayload {
            message: "Validation error".to_owned(),
            fields: error.field_errors().iter().map(|(field, _)| field.to_string()).collect(),
        }
    }
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(move || {
        App::new()
            .app_data(QsQueryConfig::default().error_handler(|err, _| {
                let json_error = match &err {
                    Error::Validate(error) => ValidationErrorJsonPayload::from(error),
                    _ => ValidationErrorJsonPayload { message: err.to_string(), fields: Vec::new() },
                };
                error::InternalError::from_response(err, HttpResponse::Conflict().json(json_error)).into()
            }))
            .service(web::resource("{path:.*}").route(web::get().to(index)))
    })
    .bind("127.0.0.1:8080")?
    .run()
    .await
}

@NexRX
Copy link

NexRX commented Mar 10, 2023

Sorry to disturb this thread but I'm a lit bit stuck trying to implement this myself.
How does putting that closure (that handles the error) in the app_data actually get triggered?

I've copied that example and when i cause a validation error, It never triggers the closure. I'm not even sure why I would.
I'm pretty new to actix so maybe I'm missing something obvious?

@singulared
Copy link
Collaborator

Hi, @NexRX! If it's actual can you show MRE?

@NexRX
Copy link

NexRX commented Jul 5, 2023

Hi, @NexRX! If it's actual can you show MRE?

I'm confused. Was this an accident?
I haven't worked with this crate for a while.

Ignore me, I'm no longer using actix so can't verify if it was just me doing something wrong.

@nhnansari
Copy link

The code given in the comment is not correct and throws an error
Error::Validate(error) => ValidationErrorJsonPayload::from(error), | -------------------------------- ^^^^^ the trait 'std::convert::From<&validator::types::ValidationErrors>' is not implemented for 'ValidationErrorJsonPayload'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants