Zum Hauptinhalt springen

3. Antwortformate und Fehlerbehandlung

Alle Aufrufe der V5 API liefern ein typisiertes DTO oder boolean/long zurück. Im Fehlerfall werden die folgenden sicheren Standardwerte zurückgegeben.

3.1 V5-Antwortmuster

MethodenmusterRückgabe bei ErfolgRückgabe bei Fehler
create(req) / update(id, req) / get(id)*ResponseV5-Instanznull
list()-FamilieList<*ResponseV5>leere Liste (niemals null)
delete(id)truefalse
exists(id)true (vorhanden)false (nicht vorhanden oder Fehler)
count()-Familielong (≥0)0
Order-Lebenszyklus (start/end/pause/resume/abort)true (Erfolg)false (z. B. Übergang nicht möglich)

Es werden keine Exceptions geworfen. HTTP-Fehler, Server-ERROR und fehlgeschlagenes JSON-Parsing werden allesamt durch die sicheren Standardwerte aus der obigen Tabelle abgefangen. Die Fehlerursache lässt sich im Debug-Log oder in _code/_message des Envelope nachvollziehen.

3.2 Internes Wire-Format (zur Information)

Der V5-Server antwortet mit einem Envelope der folgenden Form. Die Client-Bibliothek parst diesen automatisch, im normalen Betrieb müssen Sie sich also nicht darum kümmern.

// 단건 성공
{ "_status": "OK", "data": { ... } }

// 목록 성공
{ "_status": "OK", "data": [ { ... }, { ... } ] }

// 목록 — items 키 안에 배열
{ "_status": "OK", "data": { "items": [ ... ] } }

// 에러
{
"_status": "ERROR",
"_code": "E1002",
"_message": "validation failed: ...",
"_http_status": 400
}

3.3 Zuordnung der V5-ErrorCodes

Wenn der Server eine ERROR-Antwort sendet, enthält das Feld _code einen der folgenden Codes.

CodeBedeutungTypische Ursache
E1001INVALID_INPUTPflichtfeld fehlt, Typkonflikt
E1002VALIDATION_FAILEDVerstoß gegen ID-Präfix (SITE_ usw.)
E1100UNAUTHORIZEDapi_key fehlt oder ist ungültig
E1101FORBIDDENUnzureichende Berechtigung
E1200CONFLICTDoppelte ID, FK-Konflikt
E1300NOT_FOUNDKeine Entsprechung zur ID
E1400DOMAIN_RULE_VIOLATIONz. B. Order-Statusübergang nicht möglich
E1500DEPENDENCY_FAILEDFehlende Antwort eines externen Systems
E1900INTERNAL_ERRORInterner Serverfehler

3.4 Fehlerinformationen auslesen

Da die V5-Servicemethoden den Envelope nicht direkt offenlegen, lassen sich Fehlerdetails auf zwei Wegen ermitteln.

Weg 1 — Debug-Modus

APIClient_V5 client = new APIClient_V5(proto, host, port, user, token, true);
client.connect();

SiteResponseV5 result = client.site().create(req);
if (result == null) {
// 콘솔 로그에서 envelope 확인 가능
System.err.println("등록 실패 — 디버그 로그 확인");
}

Konsolenausgabe:

[V5] POST /api/v5/site body={...}
[V5] response: 400 {"_status":"ERROR","_code":"E1002","_message":"site_id must start with SITE_"}

Weg 2 — Statische Methoden von BaseServiceV5 verwenden (eigene Erweiterung)

Die Helper von BaseServiceV5 extrahieren Fehlerinformationen aus einer JSONObject-Antwort. Das ist nützlich, wenn Sie die Bibliothek erweitern und einen eigenen Service bauen, der den Envelope erfasst.

import plantpulse.api.v5.service.BaseServiceV5;
import plantpulse.json.JSONObject;

// 환경 (envelope) JSONObject 가 있다면
String code = BaseServiceV5.getErrorCode(env); // 예: "E1002"
String message = BaseServiceV5.getErrorMessage(env); // 예: "validation failed: ..."
int httpStatus = BaseServiceV5.getHttpStatus(env); // 예: 400

3.5 Sichere Aufrufmuster

CRUD-Aufruf

import plantpulse.api.v5.dto.request.SiteRequestV5;
import plantpulse.api.v5.dto.response.SiteResponseV5;

SiteRequestV5 req = new SiteRequestV5();
req.setSite_id("SITE_DJ");
req.setSite_name("대전공장");

SiteResponseV5 created = client.site().create(req);
if (created == null) {
// 실패 처리 — 예: 알람, 재시도, 다른 경로 시도
log.warn("사이트 생성 실패");
return;
}
System.out.println("등록 완료: " + created.getSite_id());

Listenaufruf

List<SiteResponseV5> sites = client.site().list();
// 실패해도 null 이 아님 — 그대로 순회 가능
for (SiteResponseV5 s : sites) {
System.out.println(s.getSite_id());
}
if (sites.isEmpty()) {
log.info("등록된 사이트 없음");
}

Existenzprüfung → Abfrage

if (client.site().exists("SITE_DJ")) {
SiteResponseV5 site = client.site().get("SITE_DJ");
// ...
}

Order-Lebenszyklus (Rückgabe boolean)

String orderId = "ORD_20260514_001";

if (!client.order().start(orderId)) {
// 전이 불가 (예: 이미 START 상태)
log.warn("작업 시작 실패 — 현재 상태 확인");
return;
}

// 작업 진행 ...

if (!client.order().end(orderId)) {
log.warn("작업 종료 실패");
}

3.6 Wiederholungsmuster

V5 führt keine automatischen Wiederholungen durch. Wenn Sie Retries für vorübergehende Netzwerkfehler benötigen, implementieren Sie diese selbst.

import java.util.function.Supplier;

public static <T> T callWithRetry(Supplier<T> apiCall, int maxRetries, long baseDelayMs) {
int attempt = 0;
while (true) {
T result = apiCall.get();
if (result != null) return result; // 성공
if (++attempt >= maxRetries) return null; // 포기
try {
Thread.sleep(baseDelayMs * attempt); // 지수 백오프
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
return null;
}
}
}

// 사용
SiteResponseV5 site = callWithRetry(
() -> client.site().get("SITE_DJ"),
3,
1_000L);

3.7 Leere Antwort und null-Antwort unterscheiden

In V5 umfassen null bzw. false beide der folgenden Bedeutungen:

  1. Auf dem Server sind keine Daten vorhanden (NOT_FOUND, E1300)
  2. Der Aufruf ist fehlgeschlagen (Netzwerkfehler, fehlgeschlagene Validierung usw.)

Zur Unterscheidung können Sie zusätzlich exists() verwenden.

if (!client.site().exists("SITE_DJ")) {
log.info("사이트가 등록되어 있지 않습니다");
// 신규 등록 로직
} else {
SiteResponseV5 site = client.site().get("SITE_DJ");
if (site == null) {
log.error("사이트는 존재하지만 조회 실패 — 일시적 오류 가능");
}
}

Nächste Schritte