Skip to content
João Távora edited this page Jan 18, 2018 · 2 revisions

Welcome to the snooze wiki!

Here are some more details that are not specially clear or do not belong to snooze's documentation.

Defining the root url

That's done with the variable SNOOZE:*HOME-RESOURCE. If you have an index route and set it to :index, that route will also be served on /.

Redirection

It's a question of signalling a 303 with an appropriate Location: header value. I setup a helper function called redirect-to or something like that. This one is for hunchentoot but i suppose it's easy to write one for clack or anything else you use...

(defun redirect-to (url &optional
                          (format-control "Redirected")
                          format-args)
  (setf (hunchentoot:header-out :location) url)
  (snooze:http-condition 303
                         (format nil "~?" format-control format-args)))

and then in some route, say authenticate

(snooze:defroute authenticate (:post "*/*")
  (cond ((know-this-guy)
         (setup-some-session-info)
         (redirect-to "/"))
        (t
         (snooze:http-condition 403 "Unauthorized"))))

This depends on Hunchentoot or Clack, so doesn't really belong to Snooze.

Debugging

To debug a 500 error, you have several options:

(setf snooze:*catch-errors* :verbose)

This will print a backtrace to your browser (as clack-errors does, so no need of it). But you also have

(setf snooze:*catch-errors* nil)

This will let the error flow through snooze unfettered and possibly be caught by hunchentoot. But if you also

 (setf hunchentoot:*catch-errors-p* nil)

Then possibly the your Lisp debugger (SLIME or SLY) will be invoked.

All of this information is written down in the form of the docstrings of the functions in snooze's api.lisp. I recomend you read these docstrings from beginning to end (it's not a very large file). Along with the tutorial, they are the best and only documentation I have.

Understanding verbose output for HTTP conditions

This happened in issue https://github.com/joaotavora/snooze/issues/9.

When using SNOOZE:*CATCH-ERRORS* set to :verbose or nil, you might see large texts mentioning error messages even on seemingly sane input. But it's not a bug in Snooze, it's just the way snooze works. For example, any HTTP client might call your route with an empty string to a query argument. The only way to do so is to use a malformed URL and the answer from the server must be a "400: Malformed" HTTP code. You can check that Snooze does respond with that code if you examine the HTTP headers.

But, more interestingly, Snooze issues that error internally as a Lisp condition of a certain type, which in this case is SNOOZE:UNCONVERTIBLE-ARGUMENT Why? Well, you may want to present a pretty webpage explaining the error to your user. To do that, you should write a suitable SNOOZE:EXPLAIN-CONDITION method, specialized for that error class and for the text/html content type. The same if you want to provide a suitable JSON response.

See https://github.com/joaotavora/snooze#controlling-errors for more information on how to do this.

If you don't have any of these methods, SNOOZE will do the following:

  • If you have SNOOZE:*CATCH-ERRORS* set to :verbose (as you do in this example, keeping in mind that it is something that shouldn't be in a production server), you get a long message that basically reminds you that you should write a SNOOZE:EXPLAIN-CONDITION method.
  • If you have SNOOZE:*CATCH-ERRORS* set to t (the default), you get a very terse text response (along with the correct HTTP error code).