بنقرة واحدة
async-http-canonical-error-handling
Standard guard pattern for async HTTP response callbacks in Hubitat drivers
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
Standard guard pattern for async HTTP response callbacks in Hubitat drivers
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
Pattern for keeping a rolling temperature-trend sample buffer in Hubitat state, computing slope over a configurable window, and classifying rising/falling/steady/unknown.
Implement Tuya Local v3.3 Groovy drivers on Hubitat using rawSocket, AES-128-ECB, queued retries, and defensive frame parsing.
Use Hubitat async HTTP plus a request queue to authenticate with Cognito, cache tokens in state, refresh proactively, and replay a single 401-failed request.
When two agents produce overlapping skills in one session, consolidate by merging unique content into the highest-confidence existing skill.
Never let cached-state dedup bypass session validity in cloud-backed Hubitat drivers.
Correct formula for converting lat/lng degree differences to miles, with pole clamp for numerical stability
| name | Async HTTP Canonical Error Handling |
| description | Standard guard pattern for async HTTP response callbacks in Hubitat drivers |
| domain | error-handling, http, async |
| confidence | high |
| source | validated in PurpleAir v0.4.0 production release (commit 2d62b05) |
Async HTTP callbacks in Hubitat can fail silently if response handling is incomplete. The standard pattern guards against three categories of errors:
Missing any guard can crash the driver or leave it in an inconsistent state.
void parseHttpResponse(resp) {
// Guard 1: Null response (network/timeout failure)
if (!resp) {
log.warn "No response from API — scheduling retry"
scheduleRetry()
return
}
// Guard 2: HTTP error status
if (resp.hasError()) {
log.warn "HTTP ${resp.getStatus()}: ${resp.getErrorMessage()}"
// Note: if disabled, respect the "don't reschedule" directive
if (settings.updateInterval != "0") {
scheduleRetry()
}
return
}
// Guard 3: JSON parse — empty body or malformed JSON
String body = resp?.getData()?.trim()
if (!body) {
log.warn "Empty response body — no data to parse"
return // Don't retry on empty body (likely a transient condition)
}
try {
def json = parseJson(body)
// ... process json ...
} catch (e) {
log.warn "JSON parse failed: ${e.message}"
return
}
}
When polling is disabled (update interval = "0"), do NOT reschedule even on error:
void scheduleRetry() {
Integer intervalMinutes = settings.updateInterval?.toString()?.isNumber() ?
settings.updateInterval.toString().toInteger() : 60
// Key: respect disabled state even on error paths
if (intervalMinutes != 0) {
Integer backoffSeconds = calculateBackoff()
runIn(backoffSeconds, "refresh")
}
}
Applied in PurpleAir AQI v0.4.0 (commit 2d62b05):
httpResponse() handler checks !resp before accessing resp methodshasError() branch guards HTTP status codes and logs diagnostic statusparseJson() wrapped in try/catch after ?.trim() guardsscheduleRetry() respects disabled polling setting (update_interval == "0")See drivers/purpleair-aqi/purpleair-aqi.groovy lines 160–210 (v0.4.0).
❌ No null-response guard:
def json = parseJson(resp.getData()) // NPE if resp is null
❌ No hasError() check:
def json = parseJson(resp.getData()) // Ignores HTTP 500 errors
❌ No empty-body guard:
parseJson("") // Crashes with JSONException on empty string
❌ Unconditional retry on disabled polling:
if (resp.hasError()) {
runIn(60, "refresh") // Violates disabled-state contract
}
A single guard omission can turn a minor network hiccup into a cascade: driver crashes, manual hub restart required, retry storm if disabled state is ignored.