Αποκρίσεις και σφάλματα

Σύμβαση αποκρίσεων και σφαλμάτων Admin API

Αυτό το αρχείο συμπληρώνει τη σύμβαση απόκρισης κάθε endpoint στην Αναφορά endpoints. Διαβάστε τη γραμμή του για επιτυχές σώμα και τους παρακάτω πίνακες για κάθε κοινό ή ειδικό ανεπιτυχές σώμα. Τα σφάλματα χρησιμοποιούν προεπιλεγμένα διάφορες δομές συμβατότητας· οι καλούντες μπορούν να επιλέξουν έναν καθολικό φάκελο.

Προαιρετικός δομημένος φάκελος σφαλμάτων

Στείλτε αυτή την κεφαλίδα σε οποιοδήποτε endpoint:

X-Error-Format: envelope

Η σύγκριση τιμής αφαιρεί περιφερειακά κενά και αγνοεί πεζά/κεφαλαία. Με αυτή την ακριβή τιμή, κάθε απόκριση JSON με κατάσταση 400 ή υψηλότερη μετατρέπεται σε:

ErrorEnvelope = {
  error: {
    code: string,
    message: string,
    details: Record<string, unknown>,
    requestId: string
  }
}

Παράδειγμα μετατροπής προεπιλεγμένου σώματος επικύρωσης:

{
  "error": {
    "code": "VALIDATION_FAILED",
    "message": "Invalid request",
    "details": {
      "fields": {
        "name": ["String must contain at least 1 character(s)"]
      }
    },
    "requestId": "integration-42"
  }
}

Οι κανόνες μετατροπής είναι ακριβείς:

  • Το validationErrors γίνεται details.fields και το code γίνεται VALIDATION_FAILED, ακόμη αν το προεπιλεγμένο σώμα είχε κωδικό τομέα.
  • Το προεπιλεγμένο code ανώτατου επιπέδου διατηρείται όταν δεν υπάρχουν πεδία επικύρωσης.
  • Οι άλλες ιδιότητες ανώτατου επιπέδου εκτός error, message, validationErrors και code μετακινούνται στο details· π.χ. το limit εξαγωγής αναφοράς γίνεται details.limit.
  • Ένα error συμβολοσειράς ανώτατου επιπέδου γίνεται message. Αν δεν υπάρχει, χρησιμοποιείται η εφεδρική τιμή κατάστασης.
  • Οι εφεδρικοί κωδικοί είναι AUTH_REQUIRED (401), PERMISSION_DENIED (403), RESOURCE_NOT_FOUND (404), CONFLICT (409), VALIDATION_FAILED (422 και άλλα μη ταξινομημένα 4xx), RATE_LIMITED (429), EXTERNAL_PROVIDER_FAILED (502) και INTERNAL_ERROR (άλλα 5xx, περιλαμβανομένου του 503).
  • Το requestId είναι η ακριβής κεφαλίδα απόκρισης X-Request-Id. ID αιτήματος του καλούντος χρησιμοποιείται μόνο αν ταιριάζει με [A-Za-z0-9._:-]{1,128} μετά περικοπή· αλλιώς ο διακομιστής δημιουργεί UUID.

Η μετατροπή δεν αλλάζει κατάσταση ή κεφαλίδες άσχετες με το σώμα. Ισχύει και σε ιδιοδύναμες επαναλήψεις βάσει της κεφαλίδας X-Error-Format του επαναληπτικού αιτήματος. Οι δυαδικές επιτυχείς αποκρίσεις παραμένουν δυαδικές· τα JSON σφάλματά τους μπαίνουν σε φάκελο. Οι υπόλοιποι πίνακες δείχνουν προεπιλεγμένα σώματα· οι παραπάνω κανόνες δίνουν το άλλο πιθανό σώμα για κάθε γραμμή.

Σημειογραφία αποκρίσεων

ValidationError = {
  validationErrors: Record<string, string[]>,
  code?: string
}

CodedError = {
  error: string,
  code: string,
  // a route may add fields explicitly listed below
}

PlainError = { error: string }

Το error και το κείμενο επικύρωσης είναι περιγραφικά, όχι σταθερό προγραμματιστικό κριτήριο. Διακλαδώστε βάσει code όταν υπάρχει. Η επικύρωση αιτήματος επιστρέφει 422 ValidationError· επικύρωση ολόκληρου αντικειμένου μπορεί να δώσει { "validationErrors": {} } αν δεν ορίζεται πεδίο. Μη έγκυρο JSON και απρόβλεπτες αποτυχίες επιστρέφουν το καθολικό 500 PlainError παρακάτω.

Όλα τα παραδείγματα JSON είναι ακριβείς δομές σώματος. Το κείμενο <message> είναι το επιστρεφόμενο μήνυμα επικύρωσης ή λειτουργίας και είναι συμβολοσειρά JSON, όχι κυριολεκτική τιμή σε αγκύλες γωνίας.

Σειρά επεξεργασίας αιτήματος

Τα αιτήματα επεξεργάζονται με αυτή τη σειρά:

  1. ρύθμιση και έλεγχος ταυτότητας διακριτικών χώρου εργασίας·
  2. πολιτική κεντρικού συστήματος και όρια διακριτικού/χώρου εργασίας·
  3. φιλτράρισμα τρεχόντων δικαιωμάτων·
  4. για κάθε μεταβολή, επικύρωση/δέσμευση ιδιοδυναμίας·
  5. έλεγχοι πεδίων πρόσβασης endpoint, επικύρωση αιτήματος και ζητούμενη λειτουργία.

Συνεπώς, μια μεταβολή με έγκυρο αλλά ανεπαρκές διακριτικό πρέπει επίσης να στέλνει Idempotency-Key. Μια ολοκληρωμένη απόκριση μεταβολής 403, 404, 409 ή 422 επαναλαμβάνεται με το ίδιο κλειδί/αίτημα.

Αποκρίσεις ελέγχου ταυτότητας, πολιτικών και περιορισμού αιτημάτων

Αυτές οι αποκρίσεις μπορούν να προκύψουν σε κάθε καταχωρισμένο endpoint /v2/admin πριν την ειδική επεξεργασία του.

ΚατάστασηΠότεΑκριβές σώμαΣχετικές κεφαλίδες
401Απόν, διπλό, ενωμένο με κόμμα, μη-Bearer, κακοσχηματισμένο, άγνωστο, ληγμένο, ανακληθέν ή άλλο μη έγκυρο διακριτικό χώρου εργασίας{ "error": "Unauthorized", "code": "INVALID_WORKSPACE_TOKEN" }WWW-Authenticate: Bearer, Cache-Control: no-store
404Το διακριτικό είναι έγκυρο αλλά το κεντρικό σύστημα χώρου εργασίας δεν έχει adminApiEnabled{ "error": "Not Found" }Cache-Control: no-store
429Εξαντλήθηκε ο κάδος αιτημάτων ανά διακριτικό ή χώρο εργασίας{ "error": "Too many attempts. Please try again later." }Retry-After: <seconds>
503Ο έλεγχος ταυτότητας διακριτικού χώρου εργασίας δεν είναι προσωρινά διαθέσιμος{ "error": "Admin API workspace-token configuration is unavailable", "code": "WORKSPACE_API_CONFIG_UNAVAILABLE" }—
503Αποτυχία αναζήτησης πολιτικής κεντρικού συστήματος ή εξουσιοδότησης τρεχόντων δικαιωμάτων{ "error": "Workspace authorization is temporarily unavailable", "code": "WORKSPACE_AUTHORIZATION_UNAVAILABLE" }—

Η πρόσβαση API περιλαμβάνεται σε κάθε πρόγραμμα. Η απενεργοποίηση της ρύθμισης adminApiEnabled του κεντρικού συστήματος επιστρέφει 404· η απώλεια πρόσθετου δικαιώματος λειτουργίας αφαιρεί μόνο τα επηρεαζόμενα πεδία πρόσβασης. Η προκύπτουσα άρνηση χρησιμοποιεί την παρακάτω απόκριση, όχι διαδικασία ανανέωσης διακριτικού.

Πεδίο πρόσβασης, ιδιοδυναμία, ανάλυση, ιδιοκτησία και απρόβλεπτες αποτυχίες

Ισχύει γιαΚατάστασηΑκριβές σώμαΚεφαλίδες/σημειώσεις
Κάθε διαδρομή μετά τον έλεγχο ταυτότητας403{ "error": "Insufficient workspace-token scope", "code": "INSUFFICIENT_SCOPE" }Επιστρέφεται όταν λείπει οποιοδήποτε απαιτούμενο πεδίο πρόσβασης.
Κάθε μεταβολή400{ "error": "Idempotency-Key is required for this operation", "code": "IDEMPOTENCY_KEY_REQUIRED" }Δεν δόθηκε κλειδί.
Κάθε μεταβολή400{ "error": "Exactly one Idempotency-Key is required", "code": "INVALID_IDEMPOTENCY_KEY" }Διπλή κεφαλίδα ή τιμές ενωμένες με κόμμα.
Κάθε μεταβολή400{ "error": "Idempotency-Key must contain 1 to 255 visible characters", "code": "INVALID_IDEMPOTENCY_KEY" }Κενό, πολύ μεγάλο ή περιέχει χαρακτήρα ελέγχου.
Κάθε μεταβολή409{ "error": "Idempotency-Key was already used with a different request", "code": "IDEMPOTENCY_CONFLICT" }Ίδιο διακριτικό/μέθοδος/διαδρομή/κλειδί, διαφορετικό URL ή σώμα.
Κάθε μεταβολή409{ "error": "Request is already processing", "code": "IDEMPOTENT_REQUEST_PROCESSING" }Retry-After: 5.
Κάθε μεταβολή409{ "error": "Previous request outcome is unknown; verify its effects before attempting the operation again", "code": "IDEMPOTENCY_OUTCOME_UNKNOWN" }Έληξε η προηγούμενη μίσθωση επεξεργασίας, έκλεισε η σύνδεση ή το αίτημα ολοκληρώθηκε με 5xx.
Κάθε μεταβολή503{ "error": "Idempotency storage unavailable", "code": "IDEMPOTENCY_UNAVAILABLE" }Το API δεν μπορεί να ελέγξει ή να αποθηκεύσει την εγγραφή ιδιοδυναμίας.
Οποιοδήποτε endpoint με μη έγκυρο σχήμα ερωτήματος/σώματος/διαδρομής422{ "validationErrors": { "<field>": ["<message>"] } }Μπορεί να υπάρχουν πολλά πεδία/μηνύματα. Οι καλούντες δεν μπορούν να δίνουν cpoId· ο χώρος εργασίας προέρχεται πάντα από το διακριτικό.
Οποιοσδήποτε απόντας ένθετος πόρος ή αναγνωριστικό άλλου χώρου εργασίας404{ "error": "Workspace resource not found", "code": "RESOURCE_NOT_FOUND" }Χρησιμοποιείται σταθερά εκτός αν πίνακας παρακάτω ορίζει αλλιώς.
Οποιοδήποτε endpoint με απρόβλεπτη αποτυχία500{ "error": "Something went wrong" }Στις μεταβολές, η μεταγενέστερη επανάληψη του ίδιου κλειδιού δίνει 409 IDEMPOTENCY_OUTCOME_UNKNOWN.

Τα ID διαδρομών πόρων πρέπει να είναι θετικοί αριθμοί. Μη θετικό ή μη αριθμητικό :siteId, :chargerId, :portId, :tariffId, :profileId, :assignmentId, :userId, :rfidId, :accessId, :limitId ή :localUserId επιστρέφει 422 ValidationError, όχι 400.

Σφάλματα τοποθεσίας και διαχείρισης ισχύος

EndpointsΚατάστασηΑκριβές σώμα
Δημιουργία/ενημέρωση τοποθεσίας· επικύρωση πεδίων χώρου εργασίας422{ "validationErrors": { "<field>": ["<message>"] } }
DELETE /v2/admin/sites/:siteId όταν η τοποθεσία έχει εξαρτήσεις409{ "error": "<message>", "code": "SITE_NOT_EMPTY" }
GET /v2/admin/sites/geocode μη έγκυρη κανονικοποιημένη αναζήτηση400{ "error": "<message>", "code": "INVALID_GEOCODE_QUERY" }
Το ίδιο, πλήρης οριοθετημένη ουρά παρόχου429{ "error": "<message>", "code": "GEOCODING_BUSY" }· περιέχει Retry-After όταν δίνεται από τον γεωκωδικοποιητή
Το ίδιο, λήξη χρόνου/αποτυχία παρόχου ή απρόβλεπτο σφάλμα γεωκωδικοποιητή502{ "error": "<message>", "code": "GEOCODING_UNAVAILABLE" }· απρόβλεπτο σφάλμα χρησιμοποιεί Address search is temporarily unavailable
PUT /v2/admin/sites/:siteId/power-management μη έγκυρη ρύθμιση τοπολογίας/τομέα422{ "error": "<message>", "code": "INVALID_POWER_MANAGEMENT_CONFIGURATION" }
Το ίδιο, άρνηση/λήξη χρόνου OCPP, ταυτόχρονη αλλαγή ή διένεξη συμφωνίας409{ "error": "<message>", "code": "POWER_MANAGEMENT_CONFLICT" }

Σφάλματα φορτιστών

Το mapChargerErrors() χρησιμοποιείται για δημιουργία/ενημέρωση φορτιστή, διαπιστευτήρια, ρυθμίσεις υποδοχής, δημόσια καταχώριση, επίλυση περιεχομένου QR, μεταβολή/επαναφόρτωση ρυθμίσεων, έναρξη υλικολογισμικού, τέσσερις βασικές εντολές και αίτημα σύνθετου προγράμματος.

EndpointsΚατάστασηΑκριβές σώμα
Οποιαδήποτε παραπάνω λειτουργία με αποτυχία επικύρωσης τομέα422{ "validationErrors": { "<field>": ["<message>"] } }
Οποιαδήποτε παραπάνω λειτουργία με διένεξη κατάστασης, μοναδικότητας, εκτός σύνδεσης/OCPP, χρέωσης, Tagless, υποδοχής ή ετοιμότητας409{ "error": "<message>", "code": "CHARGER_CONFLICT" }
GET /chargers/:chargerId/sessions, μη έγκυρο προεπιλεγμένο/ρητό χρονικό διάστημα422{ "validationErrors": { "from": ["from must be before or equal to to"] } } ή { "validationErrors": { "from": ["Session range cannot exceed 90 days"] } }

Οι απλές αναγνώσεις επιστρέφουν μόνο τις κοινές αποκρίσεις 401/403/404/429/500/503 και επικύρωση ερωτήματος/διαδρομής 422. Η διαγραφή φορτιστή μπορεί να επιστρέψει κοινό 500 PlainError αν αποτύχει χωρίς πιο συγκεκριμένο σφάλμα.

Σφάλματα αναφορών

EndpointsΚατάστασηΑκριβές σώμα
Διάστημα δεδομένων/εξαγωγής όπου from >= to422{ "validationErrors": { "range": ["from must be earlier than to"] } }
Διάστημα δεδομένων/εξαγωγής άνω των 90 ημερών422{ "validationErrors": { "range": ["Report ranges cannot exceed 90 days"] } }
Μη έγκυρος αδιαφανής δρομέας δεδομένων/μετρήσεων422{ "validationErrors": { "cursor": ["<message>"] } }
GET /reports/export, αποτέλεσμα άνω των 2.000 γραμμών422{ "error": "<message>", "code": "REPORT_EXPORT_ROW_LIMIT", "limit": 2000 }
POST /reports/send, κανένα αποθηκευμένο πρόγραμμα409{ "error": "A workspace report schedule must be saved before sending", "code": "REPORT_SCHEDULE_REQUIRED" }
Το ίδιο, απόρριψη/αποτυχία υπηρεσίας email502{ "error": "Report delivery failed", "code": "REPORT_DELIVERY_FAILED" }
Απουσιάζει ιδιόκτητος πόρος προγράμματος/μετρήσεων404κοινό σώμα RESOURCE_NOT_FOUND

Η επιτυχής εξαγωγή είναι δυαδική· όλα τα σφάλματα εξαγωγής παραμένουν JSON.

Σφάλματα τιμολογίων

EndpointsΚατάστασηΑκριβές σώμα
Επικύρωση τομέα δημιουργίας/ενημέρωσης/στοιχείων/τιμών αγοράς/ανάθεσης422{ "validationErrors": { "<field>": ["<message>"] } }
Διένεξη κατάστασης/εξάρτησης/μοναδικότητας διαγραφής ή ανάθεσης τιμολογίου409{ "error": "<message>", "code": "TARIFF_CONFLICT" }
Ασυμφωνία ιδιοκτησίας τιμολογίου, ζώνης προσφορών, φορτιστή, υποδοχής, ανάθεσης ή άλλου ένθετου πόρου404κοινό σώμα RESOURCE_NOT_FOUND

Σφάλματα προφίλ φόρτισης

EndpointsΚατάστασηΑκριβές σώμα
Επικύρωση τομέα δημιουργίας/ενημέρωσης/προγράμματος/ανάθεσης422{ "validationErrors": { "<field>": ["<message>"] } }
Το προφίλ αναφέρεται από προστατευμένη χρήση409{ "error": "<message>", "code": "CHARGING_PROFILE_IN_USE" }
Διένεξη συγχρονισμού OCPP, ανάθεσης, ταυτόχρονης πρόσβασης ή άλλου προφίλ409{ "error": "<message>", "code": "CHARGING_PROFILE_CONFLICT" }
Ασυμφωνία ιδιοκτησίας προφίλ, φορτιστή, υποδοχής, ανάθεσης ή άλλου ένθετου πόρου404κοινό σώμα RESOURCE_NOT_FOUND

Σφάλματα τομέα χρηστών

Σφάλματα επικύρωσης χρήστη που ορίζουν πεδίο χρησιμοποιούν ValidationError και code· άλλα χρησιμοποιούν CodedError. Όλες οι ελλείψεις πόρων χρησιμοποιούν την κοινή μη αποκαλυπτική απόκριση RESOURCE_NOT_FOUND.

ΚατάστασηΚωδικοίΣώμα
400INVALID_USER_CURSOR{ "validationErrors": { "cursor": ["The user-list cursor is invalid for the selected status"] }, "code": "INVALID_USER_CURSOR" }
409USER_ALREADY_EXISTS, CUSTOMER_CONTRACT_MISSING, INVITATION_EMAIL_IN_USE, RFID_ALREADY_EXISTS, ACCESS_ALREADY_EXISTS, ACCESS_ALL_ALREADY_EXISTS, LIMIT_ALREADY_EXISTS, LOCAL_USER_ALREADY_EXISTS, PROTECTED_WORKSPACE_USER, TAGLESS_USER_PROTECTED, USER_RELATED_DATA{ "error": "<message>", "code": "<listed code>" }
422INVALID_EMAIL, INVALID_RFID, INVALID_LIMIT_TYPE, INVALID_LIMIT_VALUE{ "validationErrors": { "<field>": ["<message>"] }, "code": "<listed code>" }
422NO_CHARGERS_AVAILABLE{ "error": "No chargers are available", "code": "NO_CHARGERS_AVAILABLE" }
429INVITATION_RESEND_THROTTLED{ "error": "Invitation resend is temporarily unavailable", "code": "INVITATION_RESEND_THROTTLED" }· περιέχει Retry-After
503USER_CURSOR_UNAVAILABLE{ "error": "User pagination is temporarily unavailable", "code": "USER_CURSOR_UNAVAILABLE" }
404RESOURCE_NOT_FOUND{ "error": "Workspace resource not found", "code": "RESOURCE_NOT_FOUND" }

Το POST /users/invitations μπορεί επίσης να επιστρέψει κοινό 403 INSUFFICIENT_SCOPE μετά την ανάλυση σώματος αν λείπει users:access, ή αν δόθηκε RFID και λείπει users:rfid. Τα endpoints τοπικών χρηστών αναφέρουν κάθε απαιτούμενο πεδίο πρόσβασης στην Αναφορά endpoints.

Οι κωδικοί σφαλμάτων χρηστών ισχύουν ως εξής:

Ομάδα endpointsΚωδικοί τομέα χρήστη εκτός 404, επιπλέον των κοινών αποκρίσεων
GET /usersINVALID_USER_CURSOR (400), USER_CURSOR_UNAVAILABLE (503)
POST /usersUSER_ALREADY_EXISTS, TAGLESS_USER_PROTECTED (409)
PATCH /users/:userIdTAGLESS_USER_PROTECTED (409)
DELETE /users/:userIdTAGLESS_USER_PROTECTED, PROTECTED_WORKSPACE_USER, USER_RELATED_DATA (409)
Ανάγνωση στοιχείων χρήστη, οχημάτων, RFID/πρόσβασης/ορίωνκανένας κωδικός τομέα εκτός 404
Δημιουργία RFIDCUSTOMER_CONTRACT_MISSING, RFID_ALREADY_EXISTS, TAGLESS_USER_PROTECTED (409); INVALID_RFID (422)
Ενημέρωση/διαγραφή RFIDTAGLESS_USER_PROTECTED (409)
Αντικατάσταση πρόσβασηςTAGLESS_USER_PROTECTED (409); NO_CHARGERS_AVAILABLE (422)
Ανάκληση πρόσβασηςTAGLESS_USER_PROTECTED (409)
Δημιουργία/ενημέρωση ορίουTAGLESS_USER_PROTECTED, LIMIT_ALREADY_EXISTS (409); INVALID_LIMIT_TYPE, INVALID_LIMIT_VALUE (422)
Διαγραφή ορίουTAGLESS_USER_PROTECTED (409)
Δημιουργία πρόσκλησης χώρου εργασίαςCUSTOMER_CONTRACT_MISSING, INVITATION_EMAIL_IN_USE, RFID_ALREADY_EXISTS, TAGLESS_USER_PROTECTED (409)· INVALID_EMAIL/INVALID_RFID (422)· INVITATION_RESEND_THROTTLED (429) όταν ισχύει αναμονή παράδοσης
Επαναποστολή πρόσκλησης χώρου εργασίαςINVALID_EMAIL (422), INVITATION_RESEND_THROTTLED (429)
Ακύρωση πρόσκλησης χώρου εργασίαςINVALID_EMAIL (422)
Δημιουργία τοπικού χρήστη φορτιστή για υπάρχοντα πελάτηLOCAL_USER_ALREADY_EXISTS, TAGLESS_USER_PROTECTED (409)
Πρόσκληση τοπικού χρήστη φορτιστήLOCAL_USER_ALREADY_EXISTS, INVITATION_EMAIL_IN_USE, TAGLESS_USER_PROTECTED (409)· INVALID_EMAIL (422)· INVITATION_RESEND_THROTTLED (429) όταν ισχύει αναμονή παράδοσης
Ακύρωση πρόσκλησης τοπικού χρήστηINVALID_EMAIL (422)
Ενημέρωση/διαγραφή τοπικού χρήστηTAGLESS_USER_PROTECTED (409)

Όλα τα αποτελέσματα ιδιοκτησίας και απόντων πόρων σε αυτές τις ομάδες, ακόμη και μη εγγεγραμμένο email στο POST /users, χρησιμοποιούν το κοινό σώμα 404 RESOURCE_NOT_FOUND.

Αποκρίσεις χωρίς σώμα και επαναλήψεων

Μια επιτυχής απόκριση 204 δεν έχει σώμα. Αυτό ισχύει για κάθε τεκμηριωμένη διαγραφή που αναφέρει 204 empty. Μια ολοκληρωμένη ιδιοδύναμη επανάληψη ορίζει Idempotency-Replayed: true και χρησιμοποιεί την αποθηκευμένη κατάσταση/σώμα· για 204, η απόκριση HTTP παραμένει χωρίς σώμα. Το API δεν επιστρέφει ποτέ αντικείμενο επιτυχίας JSON για τεκμηριωμένη λειτουργία 204.