Errors
Every failure is a GoodchargeError with status, code, details ({ path, message }[]) and retryAfter.
| Status | code | What to do |
|---|---|---|
| 400 | invalid_json | Send valid JSON. |
| 401 | unauthorized | Check or regenerate the key. |
| 409 | not_published | Call publish before updatePoints or heartbeat. |
| 413 | payload_too_large | Keep the body under 64 KB. |
| 422 | invalid_payload | Fix the fields listed in details. |
| 429 | too_many_requests | One request per second per key; retried automatically. |
| 5xx | internal_error | Retried automatically. |
| 0 | timeout, network_error | Retried automatically. |
| 0 | invalid_api_key | The key given to the constructor is malformed. |
| 0 | invalid_option | Thrown synchronously for a malformed constructor or startHeartbeat option. publish and updatePoints reject with it, without retrying or calling the API, when the body cannot be serialised to JSON. The metrics helpers throw it for a list that is not an array of stations or holds two stations with the same label. |
| 2xx | invalid_response | goodcharge answered success but the body was not JSON; not retried. |
A 429 or 5xx is retried honouring Retry-After (seconds, or an HTTP-date) when the response carries one; a Retry-After above 60 seconds is not retried. The error is thrown instead, still carrying retryAfter so you can decide yourself whether and when to try again.
The metrics helpers throw invalid_option synchronously: metricsText and metricsResponse when called, metricsHandler when the handler is created (a handler that later fails to read a station answers 500 instead of throwing), and registerGoodchargeMetrics when it registers, also when the goodcharge metrics are already on that registry.
unknown_error is not a GoodchargeError code: it is the outcome that goodcharge_requests_total records when a call rejects with something other than a GoodchargeError. That typically happens when fetch itself misbehaves, for example a custom fetch that resolves to a value that is not a Response; the call then rejects with that original error, unchanged.
A rejected request is also shown on the station page of the portal, with its reason.