@@ -13,6 +13,7 @@ import (
1313 "time"
1414
1515 "github.com/pion/webrtc/v4"
16+ "github.com/rs/zerolog"
1617 "go.bug.st/serial"
1718
1819 "github.com/jetkvm/kvm/internal/usbgadget"
@@ -134,7 +135,7 @@ func onRPCMessage(message webrtc.DataChannelMessage, session *Session) {
134135 }
135136
136137 scopedLogger .Trace ().Msg ("Calling RPC handler" )
137- result , err := callRPCHandler (handler , request .Params )
138+ result , err := callRPCHandler (scopedLogger , handler , request .Params )
138139 if err != nil {
139140 scopedLogger .Error ().Err (err ).Msg ("Error calling RPC handler" )
140141 errorResponse := JSONRPCResponse {
@@ -472,7 +473,7 @@ type RPCHandler struct {
472473}
473474
474475// call the handler but recover from a panic to ensure our RPC thread doesn't collapse on malformed calls
475- func callRPCHandler (handler RPCHandler , params map [string ]interface {}) (result interface {}, err error ) {
476+ func callRPCHandler (logger zerolog. Logger , handler RPCHandler , params map [string ]interface {}) (result interface {}, err error ) {
476477 // Use defer to recover from a panic
477478 defer func () {
478479 if r := recover (); r != nil {
@@ -486,11 +487,11 @@ func callRPCHandler(handler RPCHandler, params map[string]interface{}) (result i
486487 }()
487488
488489 // Call the handler
489- result , err = riskyCallRPCHandler (handler , params )
490- return result , err
490+ result , err = riskyCallRPCHandler (logger , handler , params )
491+ return result , err // do not combine these two lines into one, as it breaks the above defer function's setting of err
491492}
492493
493- func riskyCallRPCHandler (handler RPCHandler , params map [string ]interface {}) (interface {}, error ) {
494+ func riskyCallRPCHandler (logger zerolog. Logger , handler RPCHandler , params map [string ]interface {}) (interface {}, error ) {
494495 handlerValue := reflect .ValueOf (handler .Func )
495496 handlerType := handlerValue .Type ()
496497
@@ -499,20 +500,24 @@ func riskyCallRPCHandler(handler RPCHandler, params map[string]interface{}) (int
499500 }
500501
501502 numParams := handlerType .NumIn ()
502- args := make ([]reflect.Value , numParams )
503- // Get the parameter names from the RPCHandler
504- paramNames := handler .Params
503+ paramNames := handler .Params // Get the parameter names from the RPCHandler
505504
506505 if len (paramNames ) != numParams {
507- return nil , errors .New ("mismatch between handler parameters and defined parameter names" )
506+ err := fmt .Errorf ("mismatch between handler parameters (%d) and defined parameter names (%d)" , numParams , len (paramNames ))
507+ logger .Error ().Strs ("paramNames" , paramNames ).Err (err ).Msg ("Cannot call RPC handler" )
508+ return nil , err
508509 }
509510
511+ args := make ([]reflect.Value , numParams )
512+
510513 for i := 0 ; i < numParams ; i ++ {
511514 paramType := handlerType .In (i )
512515 paramName := paramNames [i ]
513516 paramValue , ok := params [paramName ]
514517 if ! ok {
515- return nil , errors .New ("missing parameter: " + paramName )
518+ err := fmt .Errorf ("missing parameter: %s" , paramName )
519+ logger .Error ().Err (err ).Msg ("Cannot marshal arguments for RPC handler" )
520+ return nil , err
516521 }
517522
518523 convertedValue := reflect .ValueOf (paramValue )
@@ -529,7 +534,7 @@ func riskyCallRPCHandler(handler RPCHandler, params map[string]interface{}) (int
529534 if elemValue .Kind () == reflect .Float64 && paramType .Elem ().Kind () == reflect .Uint8 {
530535 intValue := int (elemValue .Float ())
531536 if intValue < 0 || intValue > 255 {
532- return nil , fmt .Errorf ("value out of range for uint8: %v" , intValue )
537+ return nil , fmt .Errorf ("value out of range for uint8: %v for parameter %s " , intValue , paramName )
533538 }
534539 newSlice .Index (j ).SetUint (uint64 (intValue ))
535540 } else {
@@ -545,12 +550,12 @@ func riskyCallRPCHandler(handler RPCHandler, params map[string]interface{}) (int
545550 } else if paramType .Kind () == reflect .Struct && convertedValue .Kind () == reflect .Map {
546551 jsonData , err := json .Marshal (convertedValue .Interface ())
547552 if err != nil {
548- return nil , fmt .Errorf ("failed to marshal map to JSON: %v" , err )
553+ return nil , fmt .Errorf ("failed to marshal map to JSON: %v for parameter %s " , err , paramName )
549554 }
550555
551556 newStruct := reflect .New (paramType ).Interface ()
552557 if err := json .Unmarshal (jsonData , newStruct ); err != nil {
553- return nil , fmt .Errorf ("failed to unmarshal JSON into struct: %v" , err )
558+ return nil , fmt .Errorf ("failed to unmarshal JSON into struct: %v for parameter %s " , err , paramName )
554559 }
555560 args [i ] = reflect .ValueOf (newStruct ).Elem ()
556561 } else {
@@ -561,30 +566,40 @@ func riskyCallRPCHandler(handler RPCHandler, params map[string]interface{}) (int
561566 }
562567 }
563568
569+ logger .Trace ().Interface ("args" , args ).Msg ("Calling RPC handler" )
564570 results := handlerValue .Call (args )
565571
566572 if len (results ) == 0 {
567573 return nil , nil
568574 }
569575
570576 if len (results ) == 1 {
571- if results [0 ].Type ().Implements (reflect .TypeOf ((* error )(nil )).Elem ()) {
572- if ! results [0 ].IsNil () {
573- return nil , results [0 ].Interface ().(error )
574- }
575- return nil , nil
577+ if ok , err := asError (results [0 ]); ok {
578+ return nil , err
576579 }
577580 return results [0 ].Interface (), nil
578581 }
579582
580- if len (results ) == 2 && results [1 ].Type ().Implements (reflect .TypeOf ((* error )(nil )).Elem ()) {
581- if ! results [1 ].IsNil () {
582- return nil , results [1 ].Interface ().(error )
583+ if len (results ) == 2 {
584+ if ok , err := asError (results [1 ]); ok {
585+ if err != nil {
586+ return nil , err
587+ }
583588 }
584589 return results [0 ].Interface (), nil
585590 }
586591
587- return nil , errors .New ("unexpected return values from handler" )
592+ return nil , fmt .Errorf ("too many return values from handler: %d" , len (results ))
593+ }
594+
595+ func asError (value reflect.Value ) (bool , error ) {
596+ if value .Type ().Implements (reflect .TypeOf ((* error )(nil )).Elem ()) {
597+ if value .IsNil () {
598+ return true , nil
599+ }
600+ return true , value .Interface ().(error )
601+ }
602+ return false , nil
588603}
589604
590605func rpcSetMassStorageMode (mode string ) (string , error ) {
0 commit comments