joaotavora / snooze

Common Lisp RESTful web development
207 stars 22 forks source link

A route with an empty argument throws an error "Can't read from an empty string" #9

Closed vindarel closed 6 years ago

vindarel commented 6 years ago

I had this route, checking if its parameter is void:

(defroute torrents (:get :text/html &key query)
          ;; now fails if no query. How do we do ?
          (if query
              (print-results (torrents:async-torrents query) query)
              (redirect-to "index")))

it worked (mmh… can't be 100% sure now), but now I get an exception from this fix when I explicitly go to an url like torrents&query=, with a trailing =. The routes torrents&query (no =) or torrents do not throw a condition and do redirect to my index.

#<ERROR-WHEN-EXPLAINING #<UNCONVERTIBLE-ARGUMENT 400: Malformed arg for resource TORRENTS>> Here's a little bit more information: 
You got a #<ERROR-WHEN-EXPLAINING 
#<UNCONVERTIBLE-ARGUMENT 400: Malformed arg for resource TORRENTS>> because: 
SNOOZE:EXPLAIN-CONDITION was trying to explain to the user the condition #<UNCONVERTIBLE-ARGUMENT 400: Malformed arg for resource TORRENTS>. You got a #<UNCONVERTIBLE-ARGUMENT 400: Malformed arg for resource TORRENTS> because: 
SNOOZE:URI-TO-ARGUMENTS was trying to make sense of 
the key-value-pair "query" and "" when it caught #<SNOOZE-READER-ERROR Can't read from an empty string> 

No more interesting information on #<SNOOZE-READER-ERROR 
Can't read from an empty string>, sorry

I highlight:

SNOOZE:URI-TO-ARGUMENTS was trying to make sense of the key-value-pair "query" and "" when it caught #<SNOOZE-READER-ERROR Can't read from an empty string>

Maybe can Snooze better handle empty strings ?

joaotavora commented 6 years ago

I forgot to answer this a week ago.

Look, this isn't really a bug, it's just the way snooze works. Any HTTP client might call your route with an empty string to the "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.

So Snooze issues that error internally as a Lisp condition, and that's OK. Now, if you want to present a pretty webpage explaining the error you should write a suitable SNOOZE:EXPLAIN-CONDITIONmethod. The same if you want to provide a suitable JSON response. If you don't have any of these methods, SNOOZE will do the following:

I'm assigning this a "question" label and adding a WIKI entry.