1:- module(jsonrpc_errors, [
    2  dispatch_exception/4,
    3  server_error/3,
    4
    5  unknown_method/1,
    6  unknown_method/3,
    7  unknown_error/3,
    8  
    9  parse_error/1,
   10  invalid_request/1
   11
   12  ]).   13
   14:- use_module(library(log4p)).   15:- use_module('./protocol').   16
   17:- meta_predicate
   18  server_error(*,:,:),
   19  declared_server_error(*,:,:),
   20  find_handler(*, :, :).   21
   22:- dynamic declared_server_error/3.   23
   24dispatch_exception(Server, Message, Exception, Response) :-
   25  % declared_server_error(Server, Exception, Module:Handler),
   26  find_handler(Server, Exception, Module:Handler),
   27  debug('found error handler %w',[Module:Handler]),
   28  (apply(Module:Handler, [Server, Exception, Error])
   29    -> true
   30    ; unknown_error(Server, Exception, Error)
   31    ),
   32  BaseResponse = _{error: Error},
   33  (Id = Message.get(id) ->
   34    Response = BaseResponse.put(id,Id) ;
   35    Response = BaseResponse).
   36  
   37% Typical case
   38find_handler(Server, Exception, Module:Handler) :-
   39  declared_server_error(Server, Exception, Module:Handler), !.
   40
   41% Unknown method
   42% :- server_error(_,unknown_method(_),jsonrpc_server:unknown_method).
   43find_handler(_Server, jsonrpc_errors:unknown_method(_), jsonrpc_errors:unknown_method) :- !.
   44
   45% Module agnostic exception check
   46find_handler(Server, _:Exception, Module:Handler) :-
   47  declared_server_error(Server, _:Exception, Module:Handler), !.
   48
   49% Unknown error -- if fall through to it, not recognized
   50% :- server_error(_,_,jsonrpc_server:unknown_error).
   51find_handler(_Server, Exception, jsonrpc_errors:unknown_error) :- 
   52  warn("Using unknown error handler for %w",[Exception]),
   53  !.
   54
   55server_error(Server, Error, Module:Handler) :-
   56  Clause = declared_server_error(Server, Error, Module:Handler),
   57  ( Clause ; assertz(Clause) ).
   58
   59:- dynamic unknown_method/1.   60
   61unknown_method(Server, unknown_method(Method),Error) :-
   62  warn("Method not found for %w: %w",[Server, Method]),
   63  Error = _{code: -32601, message: "Method not found", data: Method },!.
   64
   65unknown_error(_Server, Exception, Error) :-
   66  error("An unknown error occurred: %t", [Exception]),
   67  Error = _{code: -32000, message: "An unknown error occurred" }, !.
   68
   69parse_error(Out) :-
   70  Error = _{code: -32700, message: "Parse error" },
   71  Response = _{error: Error},
   72  write_message(Out, Response).
   73
   74invalid_request(Out) :-
   75  Error = _{code: -32600, message: "Invalid Request" },
   76  Response = _{error: Error},
   77  write_message(Out, Response)