From 590c606bb1c2caf3862dc1c22f86479c065e64d3 Mon Sep 17 00:00:00 2001 From: Marc Brooks Date: Wed, 21 May 2025 08:18:11 -0500 Subject: [PATCH] Handle panics when calling the RPCHandler instead of dying (#488) Added a wrapper around the callRPCHandler function to recover from panic and translate that to and error so that the RPC thread doesn't just die when something malformed comes in. This should keep the Jet flying. --- jsonrpc.go | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/jsonrpc.go b/jsonrpc.go index ca9cd34..772075b 100644 --- a/jsonrpc.go +++ b/jsonrpc.go @@ -466,7 +466,31 @@ func rpcSetTLSState(state TLSState) error { return nil } -func callRPCHandler(handler RPCHandler, params map[string]interface{}) (interface{}, error) { +type RPCHandler struct { + Func interface{} + Params []string +} + +// call the handler but recover from a panic to ensure our RPC thread doesn't collapse on malformed calls +func callRPCHandler(handler RPCHandler, params map[string]interface{}) (result interface{}, err error) { + // Use defer to recover from a panic + defer func() { + if r := recover(); r != nil { + // Convert the panic to an error + if e, ok := r.(error); ok { + err = e + } else { + err = fmt.Errorf("panic occurred: %v", r) + } + } + }() + + // Call the handler + result, err = riskyCallRPCHandler(handler, params) + return result, err +} + +func riskyCallRPCHandler(handler RPCHandler, params map[string]interface{}) (interface{}, error) { handlerValue := reflect.ValueOf(handler.Func) handlerType := handlerValue.Type() @@ -563,11 +587,6 @@ func callRPCHandler(handler RPCHandler, params map[string]interface{}) (interfac return nil, errors.New("unexpected return values from handler") } -type RPCHandler struct { - Func interface{} - Params []string -} - func rpcSetMassStorageMode(mode string) (string, error) { logger.Info().Str("mode", mode).Msg("Setting mass storage mode") var cdrom bool