Skip to content

Instantly share code, notes, and snippets.

@jacobobryant
Created August 20, 2021 18:25
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jacobobryant/9b8e2560bb32ae03f9b086feebf8bece to your computer and use it in GitHub Desktop.
Save jacobobryant/9b8e2560bb32ae03f9b086feebf8bece to your computer and use it in GitHub Desktop.
Example of debugging an http endpoint (or function in general) in Biff (or Clojure in general)

Here's the send-token function from https://github.com/jacobobryant/biff/blob/master/libs/tasks/resources/biff/template/src/%7B%7Bparent-path%7D%7D/routes/auth.clj#L40:

; To send login links via email, set MAILGUN_* in config/prod.env. Otherwise
; the links will only be printed to the console.
(defn send-token [{:keys [params/email
                          biff/base-url
                          mailgun/api-key
                          biff.auth/jwt-secret]
                   :as sys}]
  (let [email (some-> email str/trim str/lower-case not-empty)
        token (misc/jwt-encrypt
                {:email email
                 :exp-in (* 60 60 24 3)}
                jwt-secret)
        url (misc/assoc-url (str base-url "/api/verify-token") :token token)
        human (human? sys)
        mock-send (and (not api-key) email human)
        send-success (when (and api-key email human)
                       (misc/send-mailgun
                         sys
                         (templates/signin {:to email :url url})))]
    (when mock-send
      (println (str "Click here to sign in as " email ": " url)))
    {:status 302
     :headers/Location (if (or send-success mock-send)
                         "/signin-sent/"
                         "/signin-fail/")}))

To debug, first save sys to a var:

(defn send-token [{:keys [...]
                   :as sys}]
  (def s sys) ; <=
  (let [email (some-> email str/trim str/lower-case not-empty)
        ...

Then eval send-token, go to the web browser, and try to sign in. Check from the repl that sys has been captured. e.g. eval (type s) and make sure it doesn't say clojure.lang.Var$Unbound.

At that point, you can get rid of the (def s sys) and start calling send-token from the repl:

(defn send-token [...]
  ...)
 
 (comment
   (send-token s) ; <= eval this
   )

Now you check the return value of send-token easily, and you can add printlns etc to send-token as needed. For example you could add this:

(defn send-token [{:keys [params/email
                          biff/base-url
                          mailgun/api-key
                          biff.auth/jwt-secret]
                   :as sys}]
  (let [email (some-> email str/trim str/lower-case not-empty)
        token (misc/jwt-encrypt
                {:email email
                 :exp-in (* 60 60 24 3)}
                jwt-secret)
        url (misc/assoc-url (str base-url "/api/verify-token") :token token)
        human (human? sys)
        mock-send (and (not api-key) email human)
        send-success (when (and api-key email human)
                       (misc/send-mailgun
                         sys
                         (templates/signin {:to email :url url})))]
    (biff.util/pprint [email token url human mock-send send-success]) ; <=
    ...)

And then see if any of the values look wrong.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment