Parsing a REST API bad request HTML-formatted response

Sometimes a bad request is made to the REST API and Jenkins responds with an HTML body describing the error. I wish to handle these responses in my jenkins-rest scripted client rather than dump the HTML back at the user in their console. So my question… is…

Do all HTML bodies of HTTP 400s from Jenkins follow the same format?

Here is an example of such a response:

<< HTTP/1.1 400 Bad Request
<< Server: Jetty(9.4.39.v20210325)
<< X-Content-Type-Options: nosniff
<< Cache-Control: must-revalidate,no-cache,no-store
<< Content-Type: text/html;charset=iso-8859-1
<< Content-Length: 572
<< "<html>[\n]"
<< "<head>[\n]"
<< "<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/> [\n]"
<< "<title>Error 400 The tokenUuid cannot be empty</title>[\n]"
<< "</head>[\n]"
<< "<body><h2>HTTP ERROR 400 The tokenUuid cannot be empty</h2[\n]"
<< "<table>[\n]"
<< "<tr><th>URI:</th><td>/user/admin/descriptorByName/jenkins.security.ApiTokenProperty/revoke</td></tr>[\n]"
<< "<tr><th>STATUS:</th><td>400</td></tr>[\n]"
<< "<tr><th>MESSAGE:</th><td>The tokenUuid cannot be empty</td></tr>[\n]"
<< "<tr><th>SERVLET:</th><td>Stapler</td></tr>[\n]"
<< "</table>[\n]"
<< "<hr><a href="https://eclipse.org/jetty">Powered by Jetty:// 9.4.39.v20210325</a><hr/>[\n]"
<< "[\n]"  
<< "</body>[\n]"
<< "</html>[\n]"

Since that says powered by jetty, I would guess it’s safe to assume for all jetty based installs it stays the same. But some people use tomcat and I dont know how different that might be

It’s probably not hard to tell jetty to do JSON errors for JSON calls. rest - How to make jetty ErrorHandler display error in json format in java - Stack Overflow
It might already do that if your set your accepts header to JSON. Lots of other frameworks in other languages do that automatically

1 Like

After setting Accept: application/json, the message returned is of the json format:

org.jclouds.http.internal.JavaUrlHttpCommandExecutorService - Sending request -1829602346: POST http://127.0.0.1:8080/user/admin/descriptorByName/jenkins.security.ApiTokenProperty/revoke HTTP/1.1
jclouds.wire - >> "tokenUuid="
jclouds.headers - >> POST http://127.0.0.1:8080/user/admin/descriptorByName/jenkins.security.ApiTokenProperty/revoke HTTP/1.1
jclouds.headers - >> Accept: application/json
jclouds.headers - >> Authorization: Basic YWRtaW46YWRtaW4=
jclouds.headers - >> Jenkins-Crumb: ea6c09c3fcf0a7638d58096d11fbc608fa8f05dcf02b3072bd75ef38a9e61f36
jclouds.headers - >> Cookie: JSESSIONID.f870fd5d=node08g9exl9u4f7516eqezzki3jhz8.node0; Path=/; HttpOnly
jclouds.headers - >> Content-Type: application/x-www-form-urlencoded
jclouds.headers - >> Content-Length: 10

org.jclouds.http.internal.JavaUrlHttpCommandExecutorService - Receiving response -1829602346: HTTP/1.1 400 Bad Request
jclouds.headers - << HTTP/1.1 400 Bad Request
jclouds.headers - << Server: Jetty(9.4.39.v20210325)
jclouds.headers - << X-Content-Type-Options: nosniff
jclouds.headers - << Cache-Control: must-revalidate,no-cache,no-store
jclouds.headers - << Content-Type: application/json
jclouds.headers - << Content-Length: 161
jclouds.wire - << "{[\n]"
jclouds.wire - << ""servlet":"Stapler",[\n]"
jclouds.wire - << ""message":"The tokenUuid cannot be empty",[\n]"
jclouds.wire - << ""url":"/user/admin/descriptorByName/jenkins.security.ApiTokenProperty/revoke",[\n]"
jclouds.wire - << ""status":"400"[\n]"
jclouds.wire - << "}"
1 Like

oh awesome, standards for the win!