[racket] web server: response terminates servlet?

From: Jay McCarthy (jay.mccarthy at gmail.com)
Date: Thu Nov 20 09:39:24 EST 2014

A response is a value. The various response/* functions just return
these values. A servlet is a "request -> response" function, which
means that the response you send back is the value the servlet
returns. Your use of an escape continuation to simulate C's "return"
statement is standard practice. However, the Web server offers an
effect function called 'send/back' with the type "response -> doesn't"
that will accept a response and send it back to the user, never
returning to the code that called it. I suspect you will find it nicer
to use this if you know the function isn't returning the response to a
DIFFERENT function that post-processes the response.

Jay

On Wed, Nov 19, 2014 at 9:45 PM, George Neuner <gneuner2 at comcast.net> wrote:
> Hi all,
>
> Using 6.0.1
>
> I was under the (maybe mistaken) impression that calling response/...
> terminated the servlet thread.   It seems though that it doesn't.  I was
> hoping to use response as an early exit, so that my servlets look like:
> e.g.,
>
> (define (user/exists request)
>   (let* [
>          (params   (request-bindings request))
>          (username (exists-binding? 'username params))
>          (response (make-hash))
>         ]
>
>     ; validate request
>     (unless username
>       (response/json (hasheq 'success #f 'msg "missing username" ))
>
>     ; get request parameters
>     (set! username (extract-binding/single 'username params))
>
>     :
>
>     ; send a real response
>     (response/json response )
>     ))
>
>
> (define (response/json obj . cookies )
>   (response/output
>       (λ (op) (write-json obj op))
>       #:code 200
>       #:message #"OK"
>       #:seconds (current-seconds)
>       #:mime-type #"application/javascript"
>       #:headers (map cookie->header cookies)
>       ))
>
> I expected that unless would bail out if the test fails. However, execution
> charges ahead into code that extracts post parameters and/or cookie values
> and then I get a contract error that terminates the servlet ... usually
> before my own error response is sent.
>
> Is response supposed to terminate the servlet?  If not, can I wrap a let/ec
> around the whole servlet and do something like:
>
> (define (user/exists request)
>   (let/ec fail
>      (let* [
>             (params   (request-bindings request))
>             (username (exists-binding? 'username params))
>             (response (make-hash))
>         ]
>
>        ; validate request
>        (unless username
>          (response/json (hasheq 'success #f 'msg "missing username" )
>           (fail))
>
>        ; get request parameters
>        (set! username (extract-binding/single 'username params))
>
>        :
>
>        ; send a real response
>        (response/json response )
>        )))
>
> or do I have to arrange that the response always is the last value produced?
>
> Thanks,
> George
>
> ____________________
>  Racket Users list:
>  http://lists.racket-lang.org/users



-- 
Jay McCarthy
http://jeapostrophe.github.io

           "Wherefore, be not weary in well-doing,
      for ye are laying the foundation of a great work.
And out of small things proceedeth that which is great."
                          - D&C 64:33


Posted on the users mailing list.