I am using databinder dispatch for making HTTP requests which works nicely, as long as the web server returns a 404.
If the request fails, the web server returns a 403 status code and provides a detailed error message in the response body as XML.
How to read the xml body (regardless of the 403), e.g. how can I make dispatch ignore all 403 errors?
My code looks like this:
class HttpApiService(val apiAccount:ApiAccount) extends ApiService {
val http = new Http
override def baseUrl() = "http://ws.audioscrobbler.com/2.0"
def service(call:Call) : Response = {
val http = new Http
var req = url(baseUrl())
var params = call.getParameterMap(apiAccount)
var response: NodeSeq = Text("")
var request: Request = constructRequest(call, req, params)
// Here a StatusCode exception is thrown.
// Cannot use StatusCode case matching because of GZIP compression
http(request <> {response = _})
//returns the parsed xml response as NodeSeq
Response(response)
}
private def constructRequest(call: Call, req: Request, params: Map[String, String]): Request = {
val request: Request = call match {
case authCall: AuthenticatedCall =>
if (authCall.isWriteRequest) req <<< params else req <<? params
case _ => req <<? params
}
//Enable gzip compression
request.gzip
}
}
I believe something like this works:
val response: Either[String, xml.Elem] =
try {
Right(http(request <> { r => r }))
} catch {
case dispatch.StatusCode(403, contents) =>
Left(contents)
}
The error will be in Left. The success will be in Right. The error is a String that should contain the XML response you desire.
If you need more, I believe you can look at HttpExecutor.x, which should give you full control. It's been a while since I've used dispatch, though.
Also, I'd suggest using more val's and less var's.