Re: [racket-users] Re: Exception throwing in web-server

2020-05-25 Thread Ryan Culpepper
As I understand the HTTP protocol (that is, some but not lots), the most
reasonable thing for the server to do if it discovers an error after the
status code has been sent seems to be to just hang up and let the client
realize that *something* went wrong. I don't mean just truncate the output;
I mean the server should say "here comes another chunk" and then close the
TCP connection, so it cannot be mistaken for a valid response. (The servlet
should probably make a note so the next request doesn't just fail in
exactly the same way.)

Is there are reason not to change the web server to do this automatically?

Ryan


On Mon, May 25, 2020 at 7:30 PM Norman Gray 
wrote:

>
> Thank you, Brian and Jesse, for your thoughts on this.  There may still
> be an exception problem here, though.
>
> (and sorry for being sluggish to respond)
>
> On 16 May 2020, at 20:16, Norman Gray wrote:
>
> > Now, in tracking this down I can see that I have a wrong design here:
> > the servlet has started producing output before the exception is
> > thrown, so it's at this point really too late for me to be throwing
> > errors and producing custom 5xx error pages.
>
> Brian said:
>
> > I think you need to decide when to stream, and when not to stream. In
> > my
> > web framework, most requests involve computing the entire response
> > string
> > prior to calling (response ...), so if an error is encountered, I can
> > send
> > an error response instead of a success response.
>
> and Jesse:
>
> > I suggest thinking of a servlet as a response builder, and, if
> > possible, to
> > delegate serialization of the response (output-response & friends)
> > till
> > after a response? value has been created.
>
> I agree this is the right way of thinking about things here, and it's
> reassuring to have that confirmed.  Part of what was confusing me was
> that it's not particularly clear from the documentation what
> serve/servlet's #:servlet-responder is there for.  It appears to be just
> an odd spelling of 'exception handler', as far as I can tell from the
> code.
>
> Indeed it's true that, once the HTTP status code has hit the wire,
> there's no provision in the protocol to change one's mind and come up
> with a different status (it's possible that forthcoming HTTP/3, with its
> concern to multiplex content on the wire, will come up with something
> here, but I haven't examined HTTP/3 in detail, and I'd be surprised if
> this was one of its concerns).
>
> However, a problem comes when the serialiser _does_ produce a 'real'
> exception -- meaning an exception that isn't one that I expected it to
> produce.  In that case, the response.rkt code just hangs.
>
> Consider:
>
>  #lang racket/base
>  (require web-server/servlet
>   web-server/servlet-env)
>
>  (define (make-response/output writer)
>(λ (req)
>  (response 200 #"OK" (current-seconds) #"text/plain" '()
> writer)))
>
>  (define my-app/simple
>(make-response/output
> (λ (op)
>   (display "hello" op
>  (define my-app/error
>(make-response/output
> (λ (op)
>   (error "Oooops")
>   (display "Hello" op
>  (define my-app/handlers
>(make-response/output
> (λ (op)
>   (with-handlers ((exn:fail? (λ (ex) (display "Eeek!" op
> (error "Oooops")
> (display "Hello" op)
>
>  (serve/servlet my-app/error
> #:servlet-regexp #rx""
> #:command-line? #t)
>
> If we run this server, and dereference , for
> example with curl, then the retrieval simply hangs.
>
> It appears that the handler in
> web-server-lib/web-server/response.rkt:148 is supposed to handle this
> case, but it appears not to.  I think it's possible the handler should
> be in to-chunker-t instead or as well.
>
> This means that a further possibility is to have an exception handler
> within the serialiser, and handle exceptions appropriately there (as in
> my-app/handlers above).  However all this means that a carefully-written
> servlet _must_ have such handlers, if an inadvertent exception in the
> serialiser procedure isn't to stall a client.
>
> Best wishes,
>
> Norman
>
>
> --
> Norman Gray  :  https://nxg.me.uk
> SUPA School of Physics and Astronomy, University of Glasgow, UK
>
> --
> You received this message because you are subscribed to the Google Groups
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to racket-users+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/racket-users/AB2357DF-5A41-429F-A7BB-7B4321EEDBE3%40glasgow.ac.uk
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on 

[racket-users] Re: Exception throwing in web-server

2020-05-25 Thread Norman Gray



Thank you, Brian and Jesse, for your thoughts on this.  There may still 
be an exception problem here, though.


(and sorry for being sluggish to respond)

On 16 May 2020, at 20:16, Norman Gray wrote:

Now, in tracking this down I can see that I have a wrong design here: 
the servlet has started producing output before the exception is 
thrown, so it's at this point really too late for me to be throwing 
errors and producing custom 5xx error pages.


Brian said:

I think you need to decide when to stream, and when not to stream. In 
my
web framework, most requests involve computing the entire response 
string
prior to calling (response ...), so if an error is encountered, I can 
send

an error response instead of a success response.


and Jesse:

I suggest thinking of a servlet as a response builder, and, if 
possible, to
delegate serialization of the response (output-response & friends) 
till

after a response? value has been created.


I agree this is the right way of thinking about things here, and it's 
reassuring to have that confirmed.  Part of what was confusing me was 
that it's not particularly clear from the documentation what 
serve/servlet's #:servlet-responder is there for.  It appears to be just 
an odd spelling of 'exception handler', as far as I can tell from the 
code.


Indeed it's true that, once the HTTP status code has hit the wire, 
there's no provision in the protocol to change one's mind and come up 
with a different status (it's possible that forthcoming HTTP/3, with its 
concern to multiplex content on the wire, will come up with something 
here, but I haven't examined HTTP/3 in detail, and I'd be surprised if 
this was one of its concerns).


However, a problem comes when the serialiser _does_ produce a 'real' 
exception -- meaning an exception that isn't one that I expected it to 
produce.  In that case, the response.rkt code just hangs.


Consider:

#lang racket/base
(require web-server/servlet
 web-server/servlet-env)

(define (make-response/output writer)
  (λ (req)
(response 200 #"OK" (current-seconds) #"text/plain" '() 
writer)))


(define my-app/simple
  (make-response/output
   (λ (op)
 (display "hello" op
(define my-app/error
  (make-response/output
   (λ (op)
 (error "Oooops")
 (display "Hello" op
(define my-app/handlers
  (make-response/output
   (λ (op)
 (with-handlers ((exn:fail? (λ (ex) (display "Eeek!" op
   (error "Oooops")
   (display "Hello" op)

(serve/servlet my-app/error
   #:servlet-regexp #rx""
   #:command-line? #t)

If we run this server, and dereference , for 
example with curl, then the retrieval simply hangs.


It appears that the handler in 
web-server-lib/web-server/response.rkt:148 is supposed to handle this 
case, but it appears not to.  I think it's possible the handler should 
be in to-chunker-t instead or as well.


This means that a further possibility is to have an exception handler 
within the serialiser, and handle exceptions appropriately there (as in 
my-app/handlers above).  However all this means that a carefully-written 
servlet _must_ have such handlers, if an inadvertent exception in the 
serialiser procedure isn't to stall a client.


Best wishes,

Norman


--
Norman Gray  :  https://nxg.me.uk
SUPA School of Physics and Astronomy, University of Glasgow, UK

--
You received this message because you are subscribed to the Google Groups "Racket 
Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/AB2357DF-5A41-429F-A7BB-7B4321EEDBE3%40glasgow.ac.uk.


[racket-users] Re: Exception throwing in web-server

2020-05-17 Thread Jesse Alama
Hi Norman,

On Saturday, May 16, 2020 at 9:16:18 PM UTC+2, Norman Gray wrote:
>
>
> But (a) what should I be doing? And (b) since that exception is caught 
> in this with-handlers clause, what is it that's producing the (default) 
> exception output message?  And (c) should I expect the client just to 
> hang here? 
>
> I'm guessing that an answer to (a) is 'avoid throwing exceptions inside 
> 'output', but given that that will sometimes happen, is the 
> output-response-body/chunked procedure doing the right thing here?  Am I 
> missing something? 
>

I suggest thinking of a servlet as a response builder, and, if possible, to 
delegate serialization of the response (output-response & friends) till 
after a response? value has been created. You can happily throw exceptions 
during the construction of the response? value; the exceptions will be 
handled by whatever scaffolding you're using for your web server (that is, 
directly handled using with-handlers of your own making that wraps the 
construction of the response?, or by the handler you gave as the value of 
#:servlet-responder in `serve/servlet`, and so on). Does that help?

Jesse

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/a8026ce9-5237-41b2-a95a-60e8eccc69bd%40googlegroups.com.


[racket-users] Re: Exception throwing in web-server

2020-05-17 Thread Brian Adkins
On Saturday, May 16, 2020 at 3:16:18 PM UTC-4, Norman Gray wrote:
>
> [...]
> The exception is thrown inside the 'output' procedure 
> that's provided as the last argument to the 'response' constructor (I 
> belatedly realise this is probably a bad idea). 
> [...]
> But (a) what should I be doing? And (b) since that exception is caught 
> in this with-handlers clause, what is it that's producing the (default) 
> exception output message?  And (c) should I expect the client just to 
> hang here? 
>
> I'm guessing that an answer to (a) is 'avoid throwing exceptions inside 
> 'output', but given that that will sometimes happen, is the 
> output-response-body/chunked procedure doing the right thing here?  Am I 
> missing something? 
>

I think you need to decide when to stream, and when not to stream. In my 
web framework, most requests involve computing the entire response string 
prior to calling (response ...), so if an error is encountered, I can send 
an error response instead of a success response.

Currently, the only time I stream a response is when the client is 
downloading CSV output. In that case, there is little chance of an error 
occurring once the streaming begins. I just briefly reviewed some HTTP 
protocol information, and I couldn't find anything that would allow sending 
a 500 response after the 200 response has already be sent i.e. no way to 
switch from success to error mid-stream.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/c331d8b9-ce3c-4433-b50f-37432f2a8e3e%40googlegroups.com.