We needed the response body of failed requests to an API, so we came up with this solution:
Define your own ApiHttpError
class with code
and body
(for the body text):
case class ApiHttpError(code: Int, body: String)
extends Exception("Unexpected response status: %d".format(code))
Define OkWithBodyHandler
similar to what is used in the source of displatch
:
class OkWithBodyHandler[T](f: Response => T) extends AsyncCompletionHandler[T] {
def onCompleted(response: Response) = {
if (response.getStatusCode / 100 == 2) {
f(response)
} else {
throw ApiHttpError(response.getStatusCode, response.getResponseBody)
}
}
}
Now, near your call to the code that might throw and exception (calling API
), add implicit
override to the ToupleBuilder
(again similar to the source code) and call OkWithBody
on request
:
class MyApiService {
implicit class MyRequestHandlerTupleBuilder(req: Req) {
def OKWithBody[T](f: Response => T) =
(req.toRequest, new OkWithBodyHandler(f))
}
def callApi(request: Req) = {
Http(request OKWithBody as.String).either
}
}
From now on, fetching either
will give you the [Throwable, String]
(using as.String)
, and the Throwable
is our ApiHttpError
with code
and body
.
Hope it helped.