April 24, 2026

Good Error Messages Save Time

Developers often face errors and will read error messages. So, a bad error message will use a lot of time. If there is no good information, people have to start guessing.

Bad error examples: - Do not a process with only an error code. Please explain the error in the error standard out. - "File not found error." End. What file! WHAT file was not found - etc

However, a good example is Babashka HTTP client.

Babaska Teacher
Figure 1. Babaska Teacher

In the REPL:

(http/post "http://gamlor.info/nowhere"
           {:headers {"Authorization" "Bearer open-sesame"}})
=> Execution error (ExceptionInfo) at babashka.http-client.interceptors/fn (interceptors.clj:251).
Exceptional status code: 404

Not much, but you can ask for the full error information in the REPL:

In the REPL:

*e
=>
#error
{:cause "Exceptional status code: 404",                                                         ; Error Message
 :data {:status 404,                                                                            ; HTTP response code
        :body "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">                             ; HTTP response body
               <html><head>
               <title>404 Not Found</title>
               </head><body>
               <h1>Not Found</h1>
               <p>The requested URL was not found on this server.</p>
               <p>Additionally, a 404 Not Found
               error was encountered while trying to use an ErrorDocument to handle the request.</p>
               </body></html>
               ",
        :version :http2,                                                                        ; What HTTP version
        :headers {":status" "404",                                                              ; HTTP response headers
                  "content-length" "315",
                  "content-type" "text/html; charset=iso-8859-1",
                  "date" "Mon, 20 Apr 2026 19:24:09 GMT",
                  "server" "Apache"},
        :uri #object [java.net.URI 0x5a3fadf4 "https://gamlor.info/nowhere"],                   ; URI used. HTTP redirect might change URIs.
        :request {:headers {:accept "*/*",                                                      ; HTTP request headers
                            :accept-encoding ["gzip" "deflate"],
                            :user-agent "babashka.http-client/0.4.23",
                            "Authorization" "Bearer open sesame"},
                  :uri #object [java.net.URI 0x5a3fadf4 "http://gamlor.info/nowhere"],          ; URI the request started with. HTTP redirect might change URIs.
                  :method :get}},                                                               ; HTTP verb
 :via [{:type clojure.lang.ExceptionInfo,                                                       ; Nexted exceptions info. Not relevant in this example
        :message "Exceptional status code: 404",
        :data {:status 404,
               :body "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">
                      <html><head>
                      <title>404 Not Found</title>
                      </head><body>
                      <h1>Not Found</h1>
                      <p>The requested URL was not found on this server.</p>
                      <p>Additionally, a 404 Not Found
                      error was encountered while trying to use an ErrorDocument to handle the request.</p>
                      </body></html>
                      ",
               :version :http2,
               :headers {":status" "404",
                         "content-length" "315",
                         "content-type" "text/html; charset=iso-8859-1",
                         "date" "Mon, 20 Apr 2026 19:24:09 GMT",
                         "server" "Apache"},
               :uri #object [java.net.URI 0x5a3fadf4 "https://gamlor.info/nowhere"],
               :request {:headers {:accept "*/*",
                                   :accept-encoding ["gzip" "deflate"],
                                   :user-agent "babashka.http-client/0.4.23",
                                   "Authorization" "Bearer open sesame"},
                         :uri #object [java.net.URI 0x5a3fadf4 "https://gamlor.info/nowhere"],
                         :method :get}},
        :at [babashka.http_client.interceptors$fn__11817 invokeStatic "interceptors.clj" 251]}],  ; The stack trace itself
 :trace [[babashka.http_client.interceptors$fn__11817 invokeStatic "interceptors.clj" 251]
         [babashka.http_client.interceptors$fn__11817 invoke "interceptors.clj" 246]
         [babashka.http_client.internal$then invokeStatic "internal.clj" 296]
         [babashka.http_client.internal$then invoke "internal.clj" 290]
         [babashka.http_client.internal$request$fn__11936 invoke "internal.clj" 329]
         [clojure.lang.PersistentList reduce "PersistentList.java" 146]
         [clojure.core$reduce invokeStatic "core.clj" 6964]
         [clojure.core$reduce invoke "core.clj" 6947]
         [babashka.http_client.internal$request invokeStatic "internal.clj" 327]
         [babashka.http_client.internal$request invoke "internal.clj" 303]
         [babashka.http_client$request invokeStatic "http_client.clj" 125]
         [babashka.http_client$request invoke "http_client.clj" 100]
         [babashka.http_client$get invokeStatic "http_client.clj" 132]
         [babashka.http_client$get invoke "http_client.clj" 127]
         [user$eval15344 invokeStatic "form-init8076736335536322939.clj" 1]
         [user$eval15344 invoke "form-init8076736335536322939.clj" 1]
         ...

This error is a developers dream. All information is here: 이 오류는 개발자의 꿈 이예요.정보가 다 있어요:

  • Maybe there is an error in body or headers of the HTTP response? That info is here.

  • Maybe a wrong header was sent? That info is here.

  • Maybe the redirects changed the URI in an unexpected way? That info is here.

  • Where this error come from? That info is here.

So, next time we write an error, remember the Babashka HTTP client and add enough error information

Tags: Development