Skip to content

Commit

Permalink
Extract error information from JSON.
Browse files Browse the repository at this point in the history
When OSRM returns an error, it (often?) includes an error code/message
in the returned JSON object. This change extracts this code/message and
returns it to the caller of libosrmc. This makes it easier to debug
failures, but also makes it possible to react to errors such as
`NoRoute`.

The errors are extracted as both `code`/`message`, and a new
`osrmc_error_code` is introduced to allow the caller to extract the
code.
  • Loading branch information
mjkillough authored and daniel-j-h committed Mar 17, 2019
1 parent efa047d commit 802ec5a
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 21 deletions.
2 changes: 1 addition & 1 deletion bindings/osrm_c89.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ int main(int argc, char** argv) {

/* If we got here on a failure path notify the user */
if (error) {
fprintf(stderr, "Error: %s\n", osrmc_error_message(error));
fprintf(stderr, "Error: code=%s, message=%s\n", osrmc_error_code(error), osrmc_error_message(error));
osrmc_error_destruct(error);
return EXIT_FAILURE;
}
Expand Down
59 changes: 39 additions & 20 deletions libosrmc/osrmc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,28 @@ int osrmc_is_abi_compatible(void) { return osrmc_get_version() >> 16u == OSRMC_V
/* API */

struct osrmc_error final {
std::string code;
std::string message;
};

static void osrmc_error_from_exception(const std::exception& e, osrmc_error_t* error) {
*error = new osrmc_error{"Exception", e.what()};
}

static void osrmc_error_from_json(osrm::json::Object& json, osrmc_error_t* error) try {
auto code = json.values["code"].get<osrm::json::String>().value;
auto message = json.values["message"].get<osrm::json::String>().value;
if (code.empty()) {
code = "Unknown";
}

*error = new osrmc_error{code, message};
} catch (const std::exception& e) {
osrmc_error_from_exception(e, error);
}

const char* osrmc_error_code(osrmc_error_t error) { return error->code.c_str(); }

const char* osrmc_error_message(osrmc_error_t error) { return error->message.c_str(); }

void osrmc_error_destruct(osrmc_error_t error) { delete error; }
Expand All @@ -48,7 +67,7 @@ osrmc_config_t osrmc_config_construct(const char* base_path, osrmc_error_t* erro

return reinterpret_cast<osrmc_config_t>(out);
} catch (const std::exception& e) {
*error = new osrmc_error{e.what()};
osrmc_error_from_exception(e, error);
return nullptr;
}

Expand All @@ -60,7 +79,7 @@ osrmc_osrm_t osrmc_osrm_construct(osrmc_config_t config, osrmc_error_t* error) t

return reinterpret_cast<osrmc_osrm_t>(out);
} catch (const std::exception& e) {
*error = new osrmc_error{e.what()};
osrmc_error_from_exception(e, error);
return nullptr;
}

Expand All @@ -74,7 +93,7 @@ void osrmc_params_add_coordinate(osrmc_params_t params, float longitude, float l

params_typed->coordinates.emplace_back(std::move(longitude_typed), std::move(latitude_typed));
} catch (const std::exception& e) {
*error = new osrmc_error{e.what()};
osrmc_error_from_exception(e, error);
}

void osrmc_params_add_coordinate_with(osrmc_params_t params, float longitude, float latitude, float radius, int bearing,
Expand All @@ -90,15 +109,15 @@ void osrmc_params_add_coordinate_with(osrmc_params_t params, float longitude, fl
params_typed->radiuses.emplace_back(radius);
params_typed->bearings.emplace_back(std::move(bearing_typed));
} catch (const std::exception& e) {
*error = new osrmc_error{e.what()};
osrmc_error_from_exception(e, error);
}

osrmc_route_params_t osrmc_route_params_construct(osrmc_error_t* error) try {
auto* out = new osrm::RouteParameters;

return reinterpret_cast<osrmc_route_params_t>(out);
} catch (const std::exception& e) {
*error = new osrmc_error{e.what()};
osrmc_error_from_exception(e, error);
return nullptr;
}

Expand Down Expand Up @@ -126,10 +145,10 @@ osrmc_route_response_t osrmc_route(osrmc_osrm_t osrm, osrmc_route_params_t param
if (status == osrm::Status::Ok)
return reinterpret_cast<osrmc_route_response_t>(out);

*error = new osrmc_error{"service request failed"};
osrmc_error_from_json(*out, error);
return nullptr;
} catch (const std::exception& e) {
*error = new osrmc_error{e.what()};
osrmc_error_from_exception(e, error);
return nullptr;
}

Expand All @@ -142,7 +161,7 @@ void osrmc_route_with(osrmc_osrm_t osrm, osrmc_route_params_t params, osrmc_wayp
const auto status = osrm_typed->Route(*params_typed, result);

if (status != osrm::Status::Ok) {
*error = new osrmc_error{"service request failed"};
osrmc_error_from_json(result, error);
return;
}

Expand All @@ -159,7 +178,7 @@ void osrmc_route_with(osrmc_osrm_t osrm, osrmc_route_params_t params, osrmc_wayp
(void)handler(data, name.c_str(), longitude, latitude);
}
} catch (const std::exception& e) {
*error = new osrmc_error{e.what()};
osrmc_error_from_exception(e, error);
}

void osrmc_route_response_destruct(osrmc_route_response_t response) {
Expand All @@ -175,7 +194,7 @@ float osrmc_route_response_distance(osrmc_route_response_t response, osrmc_error
const auto distance = route.values["distance"].get<osrm::json::Number>().value;
return distance;
} catch (const std::exception& e) {
*error = new osrmc_error{e.what()};
osrmc_error_from_exception(e, error);
return INFINITY;
}

Expand All @@ -188,15 +207,15 @@ float osrmc_route_response_duration(osrmc_route_response_t response, osrmc_error
const auto duration = route.values["duration"].get<osrm::json::Number>().value;
return duration;
} catch (const std::exception& e) {
*error = new osrmc_error{e.what()};
osrmc_error_from_exception(e, error);
return INFINITY;
}

osrmc_table_params_t osrmc_table_params_construct(osrmc_error_t* error) try {
auto* out = new osrm::TableParameters;
return reinterpret_cast<osrmc_table_params_t>(out);
} catch (const std::exception& e) {
*error = new osrmc_error{e.what()};
osrmc_error_from_exception(e, error);
return nullptr;
}

Expand All @@ -208,14 +227,14 @@ void osrmc_table_params_add_source(osrmc_table_params_t params, size_t index, os
auto* params_typed = reinterpret_cast<osrm::TableParameters*>(params);
params_typed->sources.emplace_back(index);
} catch (const std::exception& e) {
*error = new osrmc_error{e.what()};
osrmc_error_from_exception(e, error);
}

void osrmc_table_params_add_destination(osrmc_table_params_t params, size_t index, osrmc_error_t* error) try {
auto* params_typed = reinterpret_cast<osrm::TableParameters*>(params);
params_typed->destinations.emplace_back(index);
} catch (const std::exception& e) {
*error = new osrmc_error{e.what()};
osrmc_error_from_exception(e, error);
}

osrmc_table_response_t osrmc_table(osrmc_osrm_t osrm, osrmc_table_params_t params, osrmc_error_t* error) try {
Expand All @@ -228,10 +247,10 @@ osrmc_table_response_t osrmc_table(osrmc_osrm_t osrm, osrmc_table_params_t param
if (status == osrm::Status::Ok)
return reinterpret_cast<osrmc_table_response_t>(out);

*error = new osrmc_error{"service request failed"};
osrmc_error_from_json(*out, error);
return nullptr;
} catch (const std::exception& e) {
*error = new osrmc_error{e.what()};
osrmc_error_from_exception(e, error);
return nullptr;
}

Expand All @@ -249,15 +268,15 @@ float osrmc_table_response_duration(osrmc_table_response_t response, unsigned lo

return duration;
} catch (const std::exception& e) {
*error = new osrmc_error{e.what()};
osrmc_error_from_exception(e, error);
return INFINITY;
}

osrmc_nearest_params_t osrmc_nearest_params_construct(osrmc_error_t* error) try {
auto* out = new osrm::NearestParameters;
return reinterpret_cast<osrmc_nearest_params_t>(out);
} catch (const std::exception& e) {
*error = new osrmc_error{e.what()};
osrmc_error_from_exception(e, error);
return nullptr;
}

Expand All @@ -269,7 +288,7 @@ osrmc_match_params_t osrmc_match_params_construct(osrmc_error_t* error) try {
auto* out = new osrm::MatchParameters;
return reinterpret_cast<osrmc_match_params_t>(out);
} catch (const std::exception& e) {
*error = new osrmc_error{e.what()};
osrmc_error_from_exception(e, error);
return nullptr;
}

Expand All @@ -286,5 +305,5 @@ void osrmc_match_params_add_timestamp(osrmc_match_params_t params, unsigned time
auto* params_typed = reinterpret_cast<osrm::MatchParameters*>(params);
params_typed->timestamps.emplace_back(timestamp);
} catch (const std::exception& e) {
*error = new osrmc_error{e.what()};
osrmc_error_from_exception(e, error);
}
1 change: 1 addition & 0 deletions libosrmc/osrmc.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ typedef void (*osrmc_waypoint_handler_t)(void* data, const char* name, float lon

/* Error handling */

OSRMC_API const char* osrmc_error_code(osrmc_error_t error);
OSRMC_API const char* osrmc_error_message(osrmc_error_t error);
OSRMC_API void osrmc_error_destruct(osrmc_error_t error);

Expand Down

0 comments on commit 802ec5a

Please sign in to comment.