Skip to content

Error handling

Every driver run ends in exactly one D.success() or D.failure(D.errorType.X). The failure taxonomy is narrow on purpose — the portal uses it to distinguish transient problems from real outages in dashboards and alerts.

D.errorType.*When to use
RESOURCE_UNAVAILABLEDevice is unreachable. Ping fails, TCP connect refused, endpoint 5xx, SSH connect timeout, SNMP no-response.
AUTHENTICATION_ERRORCredentials rejected. HTTP 401/403, SSH bad-key, SNMP v3 auth failure, Telnet password prompt not satisfied.
PARSING_ERRORResponse came back but its structure is wrong. JSON.parse threw, regex didn’t match, expected field missing.
TIMEOUT_ERROROperation ran past its own timeout. Prefer over RESOURCE_UNAVAILABLE when the device answered something before the cut-off.
GENERIC_ERRORAnything else. Use sparingly — the others cover 95% of real cases.

Drivers get one shot. These shapes are wrong and will leak or double-report:

// wrong: both paths call something
function get_status() {
D.device.http.get({ url: '/a' }, function (err) {
if (err) D.failure(D.errorType.RESOURCE_UNAVAILABLE);
D.success();
});
}
// right: else or early return
function get_status() {
D.device.http.get({ url: '/a' }, function (err) {
if (err) return D.failure(D.errorType.RESOURCE_UNAVAILABLE);
D.success();
});
}

When you make multiple calls in parallel, track completion and call D.success / D.failure exactly once:

function get_status() {
var pending = 2;
var failed = false;
var results = {};
function fail(type) {
if (failed) return;
failed = true;
D.failure(type);
}
function done(key, value) {
if (failed) return;
results[key] = value;
pending -= 1;
if (pending === 0) D.success([
D.createVariable('temp', 'Temperature', results.temp, 'C', D.valueType.NUMBER),
D.createVariable('load', 'Load', results.load, '%', D.valueType.NUMBER)
]);
}
D.device.sendSSHCommand({ command: 'sensors -u' }, function (out, err) {
if (err) return fail(D.errorType.RESOURCE_UNAVAILABLE);
done('temp', parseTemp(out));
});
D.device.sendSSHCommand({ command: 'uptime' }, function (out, err) {
if (err) return fail(D.errorType.RESOURCE_UNAVAILABLE);
done('load', parseLoad(out));
});
}

If a device is slow but ultimately responds, that’s a healthy signal. If a device never responds within the driver’s timeout, prefer TIMEOUT_ERROR over RESOURCE_UNAVAILABLE — it helps dashboards distinguish slow from dead.

Every tick is an independent retry. Don’t build retry loops into the driver — they burn the per-run wall clock for no dashboard benefit. If a call fails, call D.failure and let the next tick try again.

console.error messages land in the collector log. They are visible to anyone debugging the driver but are not sent to the portal. Keep them short, factual, and free of credentials.

console.error('HTTP', response.statusCode, 'from', options.url);

See Testing & debugging for where those logs show up on the collector host.