net/http: making panic recovery optional

556 views
Skip to first unread message

Albert Strasheim

unread,
Jun 13, 2013, 5:18:56 AM6/13/13
to golan...@googlegroups.com, Brad Fitzpatrick
Howdy

We have recently refactored a few of our services to use net/http instead of home-grown TCP sockets and gob. The reduction in code was awesome.

We started out 3 years ago by building code that following some approximation to an actor model, where we recovered panics so that errors inside individual actors didn't kill the OS process.

We have since discarded this model. It was always difficult to distinguish between panics that were just an error and panics that should actually terminate the OS process due to it arriving in an insane state.

We've found that we more quickly achieved robust services when we didn't recover panics, since it immediately became apparent when a service panicked and we could spot it and fix it.

We use systemd to supervise our services, so we're not that worried about a rare panic blowing away our process. We prefer it. It makes our mistakes more visible to us.

With all this being said, we would like to be able to turn off net/http's recovery of panics. We prefer for our service to crash if there is a panic handling a request.

The recover stuff is baked in quite deep. I guess we'd be happy with putting code like:

func init() {
    http.RecoverPanics = false
}

in our services. But I'm guessing you might find this quite gross.

An alternative might be to add a Recover bool to the Server type. It can probably pass from Server to conn in newConn.

Any suggestions on how to approach this, if you agree that it should be approached? I'd be happy to prepare a CL.

Regards

Albert

Albert Strasheim

unread,
Jun 13, 2013, 5:20:12 AM6/13/13
to golan...@googlegroups.com
On Thursday, June 13, 2013 9:18:56 AM UTC, Albert Strasheim wrote:
An alternative might be to add a Recover bool to the Server type. It can probably pass from Server to conn in newConn.

It would probably be DontRecover so that it can default to false.

DisposaBoy

unread,
Jun 13, 2013, 9:00:56 AM6/13/13
to golan...@googlegroups.com
Personally I would use my own handler to recover from the panic then dump the stacks and potentially more useful info, then exit . If the http package doesn't recover from the panic then all that dies is that one goroutine not your entire process... Yes it does if the panic just so happens to reach main() but I don't think you can guarantee such a thing

Jesse McNelis

unread,
Jun 13, 2013, 9:45:52 AM6/13/13
to DisposaBoy, golang-nuts
On Thu, Jun 13, 2013 at 11:00 PM, DisposaBoy <dispo...@dby.me> wrote:
Personally I would use my own handler to recover from the panic then dump the stacks and potentially more useful info, then exit . If the http package doesn't recover from the panic then all that dies is that one goroutine not your entire process...

Where did you get that idea? 
A panic that isn't recovered within the goroutine that created it will kill the entire process.

It's simple enough to stop net/http from being able to recover panics in your handlers by having your handlers start their own goroutine. Obviously this wastes a goroutine per request, but it's a reasonable work around.



--
=====================
http://jessta.id.au

Kyle Lemons

unread,
Jun 13, 2013, 2:11:34 PM6/13/13
to gary b, golang-nuts, Brad Fitzpatrick


On Thu, Jun 13, 2013 at 7:18 AM, gary b <gary...@gmail.com> wrote:
Wrap the root handler with your own recove logic. Example: http://play.golang.org/p/-bYAyxTeVe
--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Brad Fitzpatrick

unread,
Jun 13, 2013, 2:21:32 PM6/13/13
to Kyle Lemons, gary b, golang-nuts
You can remove a few more bytes: http://play.golang.org/p/uPLZVaJz-d

Albert Strasheim

unread,
Jun 13, 2013, 2:26:14 PM6/13/13
to Brad Fitzpatrick, Kyle Lemons, gary b, golang-nuts
Hello

On Thu, Jun 13, 2013 at 6:21 PM, Brad Fitzpatrick <brad...@golang.org> wrote:
> You can remove a few more bytes: http://play.golang.org/p/uPLZVaJz-d
> On Thu, Jun 13, 2013 at 11:11 AM, Kyle Lemons <kev...@google.com> wrote:
>> Or, even easier:
>> http://play.golang.org/p/A69pyFiiMl

Thanks, this is probably palatable.

Cheers

Albert

Andrew Gerrand

unread,
Jun 13, 2013, 6:15:59 PM6/13/13
to Brad Fitzpatrick, Kyle Lemons, gary b, golang-nuts
On 14 June 2013 04:21, Brad Fitzpatrick <brad...@golang.org> wrote:
You can remove a few more bytes: http://play.golang.org/p/uPLZVaJz-d

Won't that just spawn goroutines in an infinite loop? 

Brad Fitzpatrick

unread,
Jun 13, 2013, 6:19:46 PM6/13/13
to Andrew Gerrand, Kyle Lemons, gary b, golang-nuts
Oh, hah. pre-coffee.
 

Rob Pike

unread,
Jun 13, 2013, 6:23:07 PM6/13/13
to Brad Fitzpatrick, Andrew Gerrand, Kyle Lemons, gary b, golang-nuts
Otherwise it's pretty.

-rob
Reply all
Reply to author
Forward
Message has been deleted
0 new messages