404 doesn't throw an exception
Ktor 1.2.4 - Client
- OkHttp
- JSON
- Serialization
Describe the bug It seems that it doesn't catch 404's in an error
To Reproduce
- Here's my code:
val httpClientEngine by lazy {
OkHttp.create {
if (BuildConfig.DEBUG) {
addInterceptor(HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.BODY
})
}
}
}
private val httpClient = HttpClient(httpClientEngine) {
install(JsonFeature) {
serializer = KotlinxSerializer(Json.nonstrict)
}
}
suspend fun myFunction(data: Any) = httpCall {
httpClient.call("my_invalid_url") {
contentType(ContentType.Application.Json
method = HttpMethod.Post
body = MyRequest(data)
}
}
And here's the httpCall wrapper:
suspend inline fun <T> httpCall(call: () -> T) = try {
call()
} catch (exception: ClientRequestException) {
val errorResponse = exception.response.receive<MyErrorResponse>()
var message = errorResponse.message
throw Exception(message)
}
However, 404's just pass through this.
Here's the response from the server:
<-- 404 Not Found http://127.0.0.1/my_invalid_url (420ms)
Server: nginx/1.15.12
Date: Wed, 13 Nov 2019 07:18:25 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 152
Connection: keep-alive
X-Powered-By: Express
Access-Control-Allow-Origin: *
Content-Security-Policy: default-src 'none'
X-Content-Type-Options: nosniff
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Error</title>
</head>
<body>
<pre>Cannot POST /my_invalid_url</pre>
</body>
</html>
<-- END HTTP (152-byte body)
I'm thinking I should need to register an XML serializer? But I can't find anything in the documentation. If I'm missing something, please do point me in the right direction.
Many thanks!
Expected behavior It should catch 404's as an error
Hi @kuuuurt, thanks for the report. Yep, it should be the exception here. Btw there is no XML feature out of the box.
Probably we can have an integration with https://github.com/pdvrieze/xmlutil for XML
Seems like it's just the call making errors pass through. I think there's no need for an XML (at least in my case)
What type of content do you receive from the call? The client validates a call only in call receiving.
Some JSON data which I deserialize with Kotlinx serialization. This specific case happened when I had a wrong URL and I'm just getting this
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Error</title>
</head>
<body>
<pre>Cannot POST /my_invalid_url</pre>
</body>
</html>
instead of the JSON string but when I have the correct URL and receive this:
{
code: 200
data: { ... }
}
It works as expected.
I used post<Unit> instead of call and it doesn't bypass the errors anymore.
Please check the following ticket on YouTrack for follow-ups to this issue. GitHub issues will be closed in the coming weeks.
Ticket is a bit old, but it seems to me like the HttpClient configuration misses expectSuccess = true in order for the call to fail in case of a non-20X HTTP status. See
https://ktor.io/docs/client-response-validation.html#default