huma icon indicating copy to clipboard operation
huma copied to clipboard

Make huma play well with custom error types returned from handlers

Open betaprior opened this issue 1 month ago • 0 comments

My use case is using huma with an existing backend that makes heavy use of custom error types. In echo, it was possible to write a custom error handler that uses a types switch on the custom errors. Unfortunately, with huma these errors are converted using NewError(http.StatusInternalServerError, err.Error()).

Thus, even though the docs suggest overriding huma.NewError for custom logic, it is not an ideal solution because the original error type is lost and only the string representation remains. It is possible to perform custom logic by parsing the string, but it's a far cry from a type switch.

This is despite the fact that signature of huma.NewError accepts any number or errors as arguments, so it would be perfectly feasible for a custom implementation to do arbitrary processing if these errors were actually made available.

But even more confusingly, parsing the error code string in custom NewError also doesn't seem to have the desired effect!

huma.NewError = func(status int, msg string, errs ...error) huma.StatusError {
    if strings.HasPrefix(msg, "code=404") {                                   
        status = http.StatusNotFound                                          
    }                                                                         
    return DefaultErrorHandler(status, msg, errs...)                          
}                 

This returns an ErrorModel JSON with status set to 404 but the response status is still 500 🫤

I can work around this by forgoing overloading NewError and instead using a transformer function that explicitly calls context.SetStatus(code), but this seems a bit counter-intuitive.

betaprior avatar Jun 15 '24 08:06 betaprior