You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Both sibling implementations have already moved to error objects, leaving this codebase
as the outlier:
mempool/electrs (fork of this codebase) did it in Fix JSON-RPC v2 errors mempool/electrs#103 (merged
2024-11-14): -32601 for unknown methods, -32603 for handler errors, -32700 for
unparseable JSON, -32600 for invalid request shapes — the latter two as replies
(with "id" or null) instead of today's behavior of dropping the connection.
romanz/electrs (v0.9 rewrite) goes further with a typed RpcError enum that also
distinguishes -32602 invalid params and ElectrumX-style application codes (1 bad
request, 2 daemon error).
Without codes, clients cannot programmatically distinguish error categories (bad params
vs. unknown method vs. server-side failure) short of parsing message strings, and
malformed envelopes get a connection drop instead of any reply. There is a
long-standing TODO at the conversion site in handle_command
(src/electrum/server.rs) pointing at this.
Related: #220 fixed unknown methods dropping the connection; this issue covers the
shape of error replies in general.
Auto-merges cleanly: the JsonRpcV2Error enum codes, the json_rpc_error()
helper, the -32601 catch-all for unknown methods, and the handler-error conversion
(json_rpc_error(e, Some(id), InternalError) replacing the bare-string format!).
Trivial conflicts (both sides added code at the same spots): their enum/helper vs.
this repo's RPC-event-logging macro and a #[trace] attribute. Resolution is keep
both.
Needs a manual port: the envelope-error handling (-32700/-32600 replies).
Their hunk is written against mempool's refactored connection layer
(ConnectionStream, crossbeam channels, a handle_value returning Value), which
this codebase doesn't have, and it must preserve this repo's RPC event logging inside handle_value. Roughly 30–50 lines re-implemented in the existing handle_value/handle_replies structure.
Porting the commit (rather than a fresh design) keeps the two esplora-lineage forks
behaviorally aligned and preserves the original authorship.
2. Distinguish error categories beyond the port.mempool/electrs#103 lumps all
handler errors under -32603 internal error. As part of the same change, distinguish:
-32602 invalid params, raised by the param helpers (usize_from_value, hash_from_value, ...) instead of generic message strings;
application-specific codes for cases like history-too-large or daemon failures,
matching romanz/ElectrumX conventions (1 bad request, 2 daemon error).
This requires categorizing errors that currently all arrive as ErrorKind::Msg(String)
— new ErrorKind variants in src/errors.rs and a sweep over the handlers/param
helpers to use them.
Compatibility
This changes the wire contract for errors. Anything matching on error being a string
breaks — bespoke clients, test suites, monitoring keyed on error strings. Mitigations:
Most Electrum wallet clients already handle error objects, since ElectrumX, Fulcrum,
romanz/electrs, and mempool/electrs all return them; the bare-string form here is the
nonstandard one.
mempool/electrs has shipped this contract since late 2024 to a large client
population without apparent fallout, which is decent field evidence.
Could be gated behind a config flag or a deprecation cycle if maintainers prefer a
transition period.
Summary
Electrum RPC error replies currently put a bare string in the
errormember:{"jsonrpc": "2.0", "id": 1, "error": "missing txid"}JSON-RPC 2.0 requires
errorto be an object with integercodeand stringmessage(plus optional
data):{"jsonrpc": "2.0", "id": 1, "error": {"code": -32602, "message": "missing txid"}}Both sibling implementations have already moved to error objects, leaving this codebase
as the outlier:
2024-11-14):
-32601for unknown methods,-32603for handler errors,-32700forunparseable JSON,
-32600for invalid request shapes — the latter two as replies(with
"id"ornull) instead of today's behavior of dropping the connection.RpcErrorenum that alsodistinguishes
-32602invalid params and ElectrumX-style application codes (1badrequest,
2daemon error).Without codes, clients cannot programmatically distinguish error categories (bad params
vs. unknown method vs. server-side failure) short of parsing message strings, and
malformed envelopes get a connection drop instead of any reply. There is a
long-standing TODO at the conversion site in
handle_command(
src/electrum/server.rs) pointing at this.Related: #220 fixed unknown methods dropping the connection; this issue covers the
shape of error replies in general.
Proposal
1. Port mempool/electrs#103. A trial cherry-pick of
mempool/electrs@277b05b onto current
new-indexshowsthe change is mostly directly applicable:
JsonRpcV2Errorenum codes, thejson_rpc_error()helper, the
-32601catch-all for unknown methods, and the handler-error conversion(
json_rpc_error(e, Some(id), InternalError)replacing the bare-stringformat!).this repo's RPC-event-logging macro and a
#[trace]attribute. Resolution is keepboth.
-32700/-32600replies).Their hunk is written against mempool's refactored connection layer
(
ConnectionStream, crossbeam channels, ahandle_valuereturningValue), whichthis codebase doesn't have, and it must preserve this repo's RPC event logging inside
handle_value. Roughly 30–50 lines re-implemented in the existinghandle_value/handle_repliesstructure.Porting the commit (rather than a fresh design) keeps the two esplora-lineage forks
behaviorally aligned and preserves the original authorship.
2. Distinguish error categories beyond the port. mempool/electrs#103 lumps all
handler errors under
-32603internal error. As part of the same change, distinguish:-32602invalid params, raised by the param helpers (usize_from_value,hash_from_value, ...) instead of generic message strings;matching romanz/ElectrumX conventions (
1bad request,2daemon error).This requires categorizing errors that currently all arrive as
ErrorKind::Msg(String)— new
ErrorKindvariants insrc/errors.rsand a sweep over the handlers/paramhelpers to use them.
Compatibility
This changes the wire contract for errors. Anything matching on
errorbeing a stringbreaks — bespoke clients, test suites, monitoring keyed on error strings. Mitigations:
romanz/electrs, and mempool/electrs all return them; the bare-string form here is the
nonstandard one.
population without apparent fallout, which is decent field evidence.
transition period.