From 1679870ea3c8874f0ebeeffd7c9116434384ec0a Mon Sep 17 00:00:00 2001 From: mpl Date: Tue, 17 Jan 2023 14:26:04 +0100 Subject: [PATCH] Suppress http.ErrAbortHandler panics, as in the stdlib Fixes https://github.com/traefik/traefik/issues/8937 --- interp/run.go | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/interp/run.go b/interp/run.go index fda2d85df..c2fb5689c 100644 --- a/interp/run.go +++ b/interp/run.go @@ -171,6 +171,13 @@ func originalExecNode(n *node, exec bltn) *node { return originalNode } +// cloned from net/http/server.go , so we can enforce a similar behavior: +// in the stdlib, this error is used as sentinel in panic triggered e.g. on +// request cancellation, in order to catch it and suppress it in a following defer. +// in yaegi, we use it to suppress a "panic" log message that happens in the +// same circumstances. +var errAbortHandler = errors.New("net/http: abort Handler") + // Functions set to run during execution of CFG. // runCfg executes a node AST by walking its CFG and running node builtin at each step. @@ -187,7 +194,13 @@ func runCfg(n *node, f *frame, funcNode, callNode *node) { if oNode == nil { oNode = n } - fmt.Fprintln(n.interp.stderr, oNode.cfgErrorf("panic")) + errorer, ok := f.recovered.(error) + // in this specific case, the stdlib would/will suppress the panic, so we + // suppress the logging here accordingly, to get a similar and consistent + // behavior. + if !ok || errorer.Error() != errAbortHandler.Error() { + fmt.Fprintln(n.interp.stderr, oNode.cfgErrorf("panic")) + } f.mutex.Unlock() panic(f.recovered) }