Skip to content

Is it possible to return an error that occurs within a procedure to a client? #9

@travispaul

Description

@travispaul

I'm probably missing something obvious, but I'm struggling to figure out how to return an error from within the procedure on the RPC server so that they're sent back to the client. I was hoping I to utilize easy_jsonrpc::Error but that doesn't seem to be handled specially (or I'm holding it wrong) and errors are returned in the result member instead of an error member.

I'm specifically looking to return an custom error member as mentioned by the JSON RPC spec, but I've only been able to return result:

error
This member is REQUIRED on error.
This member MUST NOT exist if there was no error triggered during invocation.
The value for this member MUST be an Object as defined in section 5.1.

I've observed such errors being return in the event of an RPC error (invalid params, method doesn't exist, etc) but would like to return my own as well.

use easy_jsonrpc::{Handler, MaybeReply, serde_json::json, Error, ErrorCode};

#[easy_jsonrpc::rpc]
pub trait Example {
    fn fault(&self, fail: bool) -> Result<String, Error>;
}

struct ExampleImpl;

impl Example for ExampleImpl {
    fn fault(&self, fail: bool) -> Result<String, Error> {
        // manually triggering an error based on a bool but this would typically 
        // occur as the result of some real error such as an ID that doesn't exist
        if fail {
            return Err(Error {
                code: ErrorCode::ServerError(123),
                message: "oof".to_string(),
                data: None
            })
        }
        Ok("ok".to_string())
    }
}

fn main() {
    let handler = &ExampleImpl {} as &dyn Example;

    let response = handler.handle_request(json!({
        "jsonrpc": "2.0",
        "method": "fault",
        "params": [true],
        "id": 1
    }));
    
    // response:
    // {
    //   "id": 1,
    //   "jsonrpc": "2.0",
    //   "result": {
    //     "Err": {
    //       "code": 123,
    //       "message": "oof"
    //     }
    //   }
    //}

    let expected = json!({
        "jsonrpc": "2.0",
        "error": {
            "code": 123,
            "message": "oof"
        },
        "id": 1
    });

    assert_eq!(response, MaybeReply::Reply(expected));
}

Any guidance on achieving those results are greatly appreciated!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions