rho
rho copied to clipboard
Customizable Error Messages
I have a requirement for my APIs where all messages are in JSON format.
Rho has several places where error messages are hard coded. I would prefer if users can specify their own error messages so they can be JSON, ProtoBuf, XML, Japanese, or whatever a user might need.
To list a few:
(Line numbers based on tag v0.18.0-M1
instead of master
for stability)
- [ ]
PathTree.scala
line 263 - [ ]
QueryParser.scala
lines 76 and 80 - [ ]
StringParser.scala
line 21 31 (A few more because of DateTime parser branch merge) - [ ]
package.scala
line 71, 81, 91, 101, 183, 259, and 264
I would LOVE to submit a PR to make this easier, but would like to discuss what the best path is to make this more usable.
The way I see it is we have 2 choices...
- Overrides
- Just override all the implicits with ones that respect the format of error messages I want
- Make
_captureMapR
inpackage.scala
protected
so i can override it when I inherit fromRhoDSL
- Typeclasses
- Make a error type class for
Paths
,Headers
,QueryParams
with an sealed class hierarchy of error types and have a default implicit function that gives the existing error messages. - Require
param
,capture
+?
, etc to take an implicit error handler of sorts.
I prefer path 2, but want some suggestions before I get start on this.
I would favor option 2 as well. Implicits in the project already are taken to its extreme, and adding more overrides could makes things harder to understand, specially when they go wrong.
Hello
Have you considered using the org.http4s.ServiceErrorHandler
? It's how http4s lets users override responses for errors. It also provides nice logging of errors by default, which I miss every time rho hits me with "The request body was malformed." and no details or logs. It may not be as fine-grained approach as typeclasses, but it seems to be enough to satisfy the need to provide custom error responses and has the advantage of being compatible with http4s (important when mixing http4s and rho services).
@RafalSumislawski The ServiceErrorHandler
can still be used with Rho, but it only triggers if there is an exception. In many places it isn't an exception, but some validation that fails. Moreover, what I want is something that gets more granular detail about the failure, so it can't quite be as generic.
If I can add my 2 cents about handling errors with ServiceErrorHandler
and rho, I find a bit tricky.
For example this exception will be handled by ServiceErrorHandler
:
"Example" **
GET / "example" |>> {
IO(throw new RuntimeException("Boom!")) *>
IO(Ok())
}
But this one not:
"Example" **
GET / "example" |>> {
throw new RuntimeException("Boom!")
Ok()
}
It would be caught and logged in PathTree.scala#136
I don't know if that is a design decision or not, but currently one needs to be very careful in the routes code.