Error Handling
All Elements Hub endpoints return a uniform JSON error response when a request cannot be fulfilled. The response carries enough information for a client to react programmatically (a stable, machine-readable errorCode) as well as for a human to debug the issue (a message and an errorUrl).
Response Format
Every error response uses the same ErrorInfo schema, regardless of which endpoint produced the error:
{
"httpStatusCode": 404,
"errorCode": "E5",
"errorUrl": "https://id.rhopointservice.com/E5",
"message": "No connected device was found with identifier '12f1d7dd07ac42a088c8f961b39d68ff'.",
"exceptionType": "ConnectedDeviceNotFoundException",
"stackTrace": null,
"innerError": null,
"details": null
}
| Field | Type | Description |
|---|---|---|
httpStatusCode |
int | The HTTP status code of the response (also present in the response headers). |
errorCode |
string | Stable, machine-readable identifier of the form E<n> (e.g. E5, E42). The single source of truth for what failed. Document and react to this value in your client. |
errorUrl |
string | null | Permanent URL with details about the error, of the form https://id.rhopointservice.com/<errorCode>. |
message |
string | Human-readable explanation of the failure, often with the offending identifier or value interpolated. |
exceptionType |
string | null | The .NET exception type that produced the error. Useful for support tickets but should not drive client logic — use errorCode instead. |
stackTrace |
string | null | Only populated in development builds. Always null in production. |
innerError |
object | null | If the error wraps another error, a nested ErrorInfo describing the cause. |
details |
object | null | Additional contextual information about the error as a free-form key/value map (e.g. parameter that failed validation). |
The errorUrl Pattern
Every errorCode resolves to a dedicated page under https://id.rhopointservice.com/. For example:
https://id.rhopointservice.com/E5— connected device not foundhttps://id.rhopointservice.com/E42— invalidimageFormatparameterhttps://id.rhopointservice.com/E16— unrecognised container format
The page is the authoritative reference for each code and is kept in sync with the codebase. Treat it as your primary lookup when you encounter an unfamiliar errorCode. Linking directly to this URL from your own application's error UI is encouraged — the URL is stable across hub releases.
How to React on the Client
Recommended pattern:
- Parse the response body as JSON whenever the HTTP status is in the
4xxor5xxrange. - Switch on
errorCode— not onmessageand not onexceptionType— to drive recovery logic. - Surface
message(and optionallyerrorUrl) in user-facing error displays. - Log the full
ErrorInfopayload, includinginnerError, for support and debugging.
Example client-side handling:
curl -i http://localhost:42042/v1/devices/does-not-exist
HTTP/1.1 404 Not Found
Content-Type: application/json
{
"httpStatusCode": 404,
"errorCode": "E5",
"errorUrl": "https://id.rhopointservice.com/E5",
"message": "No connected device was found with identifier 'does-not-exist'.",
"exceptionType": "ConnectedDeviceNotFoundException",
"stackTrace": null,
"innerError": null,
"details": null
}
Validation Errors from ASP.NET
In addition to ErrorInfo responses, a small number of endpoints — those that use built-in ASP.NET model validation — may return the standard ProblemDetails format on HTTP 400 Bad Request when a request body is structurally invalid (missing required field, wrong type). These responses look like:
{
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "One or more validation errors occurred.",
"status": 400,
"errors": {
"DeviceIdentifier": [ "The DeviceIdentifier field is required." ]
}
}
Treat ProblemDetails as an indicator that the request never reached business logic — fix the request shape, then retry. Business-logic errors always use the ErrorInfo format above.
Testing Error Handling
The hub exposes a dedicated endpoint to provoke each major error category, useful for verifying client-side handling:
POST /v1/system/errors/raise-exception
Content-Type: application/json
{ "errorType": "device" }
errorType |
Triggers |
|---|---|
device |
A simulated device-layer exception (ErrorInfo, with a non-zero errorCode). |
notfound |
An HTTP 404 with ErrorInfo. |
unhandled |
An uncaught exception, exercising the global exception handler. |
Use these in your integration tests to ensure your client correctly parses ErrorInfo and reacts on errorCode, not on transport-level details.
Best Practices
- React on
errorCode, not onmessagetext — the message is localisable and may change between releases. TheerrorCodeis contractually stable. - Always log
innerErrorchains in full. The root cause is often deeper than the top-level message suggests. - For user-facing dialogs, show
messageand link toerrorUrl. Do not surfaceexceptionTypeorstackTraceto end-users. - Treat any
5xxresponse as transient unlesserrorCodeindicates otherwise — retry with backoff before failing the operation. - Treat any
4xxresponse (except408,429) as a permanent failure of that request — fix the request before retrying.