stephenberry / glaze

Extremely fast, in memory, JSON and interface library for modern C++
MIT License
1.17k stars 115 forks source link

Is that possible for custom error to pop up as rpc::error in json-rpc? #912

Open ralphjzhang opened 6 months ago

ralphjzhang commented 6 months ago

Try to return custom errors from json-rpc server methods like

struct MyParams {};
struct MyResult {};
using MyServer = rpc::server<
    rpc::method<"MyMethod", MyParams, std::expected<MyResult, rpc::error>>>;
using MyClient = rpc::client<
    rpc::method<"MyMethod", MyParams, std::expected<MyResult, rpc::error>>>;

int main() {
  MyServer server;
  server.on<"MyMethod">([](MyParams) { return rpc::error{}; });

  MyClient client;
  auto [req, _] =
      client.request<"MyMethod">(1, MyParams{}, [](auto val, auto id) {});
  auto resp = server.call(req);

  std::println("resp: {}", resp);
}

but the response actually use the returned error as the result payload, i.e. the result look like

resp: {"jsonrpc":"2.0","result":{"unexpected":{"code":0,"message":"No error"}},"id":1}

instead of using the error as json-rpc error, like

resp: {"jsonrpc":"2.0","error":{"code":0,"message":"No error"},"id":1}

Is that possible to integrate error handling with the method handler?

ralphjzhang commented 6 months ago

I realize that adding some helper:

   template <typename Result>
   struct expected_helper
   {
      static constexpr bool is_expecting_rpc_error = false;
      using expected_t = std::expected<Result, rpc::error>;
   };
   template <typename Expected>
   struct expected_helper<expected<Expected, rpc::error>>
   {
      static constexpr bool is_expecting_rpc_error = true;
      using expected_t = std::expected<Expected, rpc::error>;
   };

and use it to extract those methods returning expected<T, rpc::error> would do the job, would that PR get accepted?

stephenberry commented 6 months ago

Ah, that was an unintended consequence of adding general support for std::expected. This should definitely be fixed. I'll experiment with a solution before I ask for a PR. Thanks for bringing this up.

stephenberry commented 6 months ago

After thinking about this some more, I have some questions. Are you trying to replace rpc::error with your own error class?

ralphjzhang commented 6 months ago

So far I find using rpc error is fine for me, but from design point of view, maybe it's a good idea to allow using, e.g, derived class of rpc error or some sort ...