@@ -99,6 +99,21 @@ fn get_status_hash(txs: Vec<(Txid, Option<BlockId>)>, query: &Query) -> Option<F
99
99
}
100
100
}
101
101
102
+ #[ repr( i16 ) ]
103
+ #[ derive( Clone , Copy , PartialEq , Eq ) ]
104
+ enum JsonRpcV2Error {
105
+ ParseError = -32700 ,
106
+ InvalidRequest = -32600 ,
107
+ MethodNotFound = -32601 ,
108
+ InternalError = -32603 ,
109
+ }
110
+ impl JsonRpcV2Error {
111
+ #[ inline]
112
+ fn into_i16 ( self ) -> i16 {
113
+ self as i16
114
+ }
115
+ }
116
+
102
117
struct Connection {
103
118
query : Arc < Query > ,
104
119
last_header_entry : Option < HeaderEntry > ,
@@ -447,7 +462,14 @@ impl Connection {
447
462
#[ cfg( feature = "electrum-discovery" ) ]
448
463
"server.add_peer" => self . server_add_peer ( params) ,
449
464
450
- & _ => bail ! ( "unknown method {} {:?}" , method, params) ,
465
+ & _ => {
466
+ warn ! ( "rpc unknown method #{} {} {:?}" , id, method, params) ;
467
+ return Ok ( json_rpc_error (
468
+ format ! ( "Method {method} not found" ) ,
469
+ Some ( id) ,
470
+ JsonRpcV2Error :: MethodNotFound ,
471
+ ) ) ;
472
+ }
451
473
} ;
452
474
timer. observe_duration ( ) ;
453
475
// TODO: return application errors should be sent to the client
@@ -461,7 +483,7 @@ impl Connection {
461
483
params,
462
484
e. display_chain( )
463
485
) ;
464
- json ! ( { "jsonrpc" : "2.0" , "id" : id , "error" : format! ( "{}" , e ) } )
486
+ json_rpc_error ( e , Some ( id ) , JsonRpcV2Error :: InternalError )
465
487
}
466
488
} )
467
489
}
@@ -558,7 +580,11 @@ impl Connection {
558
580
}
559
581
} else {
560
582
// serde_json was unable to parse
561
- invalid_json_rpc ( line)
583
+ json_rpc_error (
584
+ format ! ( "Invalid JSON: {line}" ) ,
585
+ None ,
586
+ JsonRpcV2Error :: ParseError ,
587
+ )
562
588
}
563
589
}
564
590
@@ -572,16 +598,14 @@ impl Connection {
572
598
( Some ( Value :: String ( method) ) , Value :: Array ( params) , Some ( id) ) => self
573
599
. handle_command ( method, params, id)
574
600
. unwrap_or_else ( |err| {
575
- json ! ( {
576
- "error" : {
577
- "code" : 1 ,
578
- "message" : format!( "{method} RPC error: {err}" )
579
- } ,
580
- "id" : id,
581
- "jsonrpc" : "2.0"
582
- } )
601
+ json_rpc_error (
602
+ format ! ( "{method} RPC error: {err}" ) ,
603
+ Some ( id) ,
604
+ JsonRpcV2Error :: InternalError ,
605
+ )
583
606
} ) ,
584
- _ => invalid_json_rpc ( value) ,
607
+ ( _, _, Some ( id) ) => json_rpc_error ( value, Some ( id) , JsonRpcV2Error :: InvalidRequest ) ,
608
+ _ => json_rpc_error ( value, None , JsonRpcV2Error :: InvalidRequest ) ,
585
609
}
586
610
}
587
611
@@ -661,15 +685,22 @@ impl Connection {
661
685
}
662
686
663
687
#[ inline]
664
- fn invalid_json_rpc ( input : impl core:: fmt:: Display ) -> Value {
665
- json ! ( {
688
+ fn json_rpc_error (
689
+ input : impl core:: fmt:: Display ,
690
+ id : Option < & Value > ,
691
+ code : JsonRpcV2Error ,
692
+ ) -> Value {
693
+ let mut ret = json ! ( {
666
694
"error" : {
667
- "code" : - 32600 ,
668
- "message" : format!( "invalid request: {input}" )
695
+ "code" : code . into_i16 ( ) ,
696
+ "message" : format!( "{input}" )
669
697
} ,
670
- "id" : null,
671
698
"jsonrpc" : "2.0"
672
- } )
699
+ } ) ;
700
+ if let ( Some ( id) , Some ( obj) ) = ( id, ret. as_object_mut ( ) ) {
701
+ obj. insert ( String :: from ( "id" ) , id. clone ( ) ) ;
702
+ }
703
+ ret
673
704
}
674
705
675
706
fn get_history (
0 commit comments