diff --git a/lib/browser/rpc.js b/lib/browser/rpc.js index f71eeac5..c11630b9 100644 --- a/lib/browser/rpc.js +++ b/lib/browser/rpc.js @@ -212,6 +212,23 @@ function makeRequest(url, data) { return JSON.parse(responseText); } +//returns an object from rpc serialized json value +function deserialize_json_value(value) { + let result = {}; + for (let index = 0; index < value.keys.length; index++) { + var propName = value.keys[index]; + var propValue = value.values[index]; + if (propValue.type && propValue.type == 'dict') { + result[propName] = deserialize_json_value(propValue); + } + else { + result[propName] = propValue.value; + } + } + + return result; +} + function sendRequest(command, data, host = sessionHost) { if (!host) { throw new Error('Must first create RPC session with a valid host'); @@ -226,9 +243,13 @@ function sendRequest(command, data, host = sessionHost) { let error = response && response.error; // Remove the type prefix from the error message (e.g. "Error: "). - if (error) { + if (error && error.replace) { error = error.replace(/^[a-z]+: /i, ''); } + else if (error.type && error.type == 'dict') { + let responseError = deserialize_json_value(error); + throw responseError; + } throw new Error(error || `Invalid response for "${command}"`); } diff --git a/src/rpc.cpp b/src/rpc.cpp index cb160526..4fb94670 100644 --- a/src/rpc.cpp +++ b/src/rpc.cpp @@ -360,8 +360,25 @@ json RPCServer::perform_request(std::string name, const json &args) { assert(action); m_worker.add_task([=] { - return action(args); + try { + return action(args); + } + catch (jsc::Exception ex) { + json exceptionAsJson = nullptr; + try { + exceptionAsJson = serialize_json_value(ex); + } + catch (...) { + exceptionAsJson = {{"error", "An exception occured while processing the request. Could not serialize the exception as JSON"}}; + } + + return (json){{"error", exceptionAsJson}}; + } + catch (std::exception &exception) { + return (json){{"error", exception.what()}}; + } }); + } try {