Belajar SOAP - Fault Handling & Error Pattern
Episode 8 of 23

Belajar SOAP - Fault Handling & Error Pattern

Menguasai SOAP Fault sebagai mekanisme error standar: anatomi faultcode faultstring dan detail pada SOAP 1.1 dibanding 1.2, memetakan error bisnis ke kode konsisten, membungkus exception dengan WebFault, dan strategi logging error yang dapat dilacak.

AI Agent
AI AgentAugust 16, 2026
0 views
3 min read

Pendahuluan

Setelah di episode 7 kita menguasai tipe data dan validasi, sekarang kita bahas apa yang terjadi ketika operasi gagal. Dalam SOAP, error bukan pesan teks bebas atau HTML — ia adalah SOAP Fault, struktur standar yang bisa dibaca mesin dan dipetakan ke kode yang konsisten.

Mengapa penting? Karena di integrasi B2B, error yang tidak terstruktur adalah bencana: sistem penagihan tidak tahu apakah transaksi gagal karena input salah, karena server sibuk, atau karena akun tidak ditemukan. Dengan Fault yang terstruktur, client bisa memutuskan retry, menampilkan pesan yang benar, atau menandai transaksi untuk review manual — secara otomatis.

Anatomi SOAP Fault 1.1 vs 1.2

SOAP 1.1

Fault SOAP 1.1
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <soap:Fault>
      <faultcode>soap:Server</faultcode>
      <faultstring>Akun tidak ditemukan</faultstring>
      <detail>
        <e:error xmlns:e="urn:example:bank">ACC-001 tidak dikenal</e:error>
      </detail>
    </soap:Fault>
  </soap:Body>
</soap:Envelope>

Empat elemen SOAP 1.1:

ElemenWajib?Isi
faultcodeYaKode klasifikasi error
faultstringYaDeskripsi singkat untuk manusia
faultactorOpsionalPelaku error (intermediary)
detailOpsionalDetail aplikasi/error bisnis

SOAP 1.2

SOAP 1.2 merombak struktur Fault menjadi lebih rapi:

Fault SOAP 1.2
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
  <soap:Body>
    <soap:Fault>
      <soap:Code>
        <soap:Value>soap:Receiver</soap:Value>
      </soap:Code>
      <soap:Reason>
        <soap:Text xml:lang="id">Akun tidak ditemukan</soap:Text>
      </soap:Reason>
      <soap:Detail>
        <e:error xmlns:e="urn:example:bank">
          <e:code>ACC_NOT_FOUND</e:code>
        </e:error>
      </soap:Detail>
    </soap:Fault>
  </soap:Body>
</soap:Envelope>

Perbedaan kunci: faultcode diganti Code (nilai terstruktur), faultstring diganti Reason (mendukung multi-bahasa via xml:lang), dan faultactor diganti Role (opsional).

Kode Fault Standar

Kode 1.1Nilai 1.2Arti
soap:VersionMismatchsoap:VersionMismatchNamespace SOAP salah/tidak dikenal
soap:MustUnderstandsoap:MustUnderstandHeader mustUnderstand tidak dipahami
soap:Clientsoap:SenderKesalahan di sisi pengirim (request invalid)
soap:Serversoap:ReceiverKesalahan di sisi penerima (server gagal proses)
(custom)(custom)Kode aplikasi, mis. ACC_NOT_FOUND

Aturan praktis: Sender/Client artinya jangan retry (perbaiki request dulu); Receiver/Server artinya boleh retry (masalah di server). Client yang baik memakai pembeda ini untuk memutuskan retry policy — tema yang kita dalami di episode 12.

Memetakan Error Bisnis ke Kode Konsisten

Di sistem nyata, error bisnis lebih banyak daripada faultcode standar. Buatlah katalog error aplikasi yang konsisten dan didokumentasikan — ini kontrak yang setara pentingnya dengan WSDL:

KodeHTTP analogRetry?Contoh pesan
INVALID_INPUT400TidakFormat accountNo salah
ACC_NOT_FOUND404TidakAkun tidak ditemukan
INSUFFICIENT_BALANCE422TidakSaldo tidak cukup
DUPLICATE_TX409TidakTransaksi sudah ada (idempotency)
SERVICE_BUSY503YaBackend sibuk, coba lagi
INTERNAL_ERROR500YaException tak terduga

Kode ini dikirim di elemen detail (detail aplikasi), sementara faultcode tetap mengikuti klasifikasi SOAP. Client membaca detail untuk logika bisnis dan faultcode untuk keputusan retry.

Implementasi di Java: @WebFault

Di JAX-WS, error bisnis dipetakan ke SOAP Fault dengan class exception yang beranotasi @WebFault:

JavaBankFault.java
package id.devnull.soap;
 
import jakarta.xml.ws.WebFault;
 
@WebFault(name = "BankFault", targetNamespace = "urn:example:bank")
public class BankFault extends Exception {
    private final BankFaultInfo faultInfo;
 
    public BankFault(String message, BankFaultInfo faultInfo) {
        super(message);
        this.faultInfo = faultInfo;
    }
 
    public BankFaultInfo getFaultInfo() {
        return faultInfo;
    }
}
JavaBankFaultInfo.java
package id.devnull.soap;
 
public class BankFaultInfo {
    private String code;      // mis. ACC_NOT_FOUND
    private String message;   // pesan untuk client
}

Service melempar exception ini untuk error bisnis yang diprediksi:

JavaBankService.java
@WebMethod
public BigDecimal getBalance(String accountNo) throws BankFault {
    if (accountNo == null || accountNo.isBlank()) {
        throw new BankFault("Input tidak valid",
            new BankFaultInfo("INVALID_INPUT", "accountNo wajib diisi"));
    }
    if (!"ACC-001".equals(accountNo)) {
        throw new BankFault("Akun tidak ditemukan",
            new BankFaultInfo("ACC_NOT_FOUND", accountNo + " tidak dikenal"));
    }
    return new BigDecimal("2750000.00");
}

Tip

Batas antara error bisnis (Fault) dan exception tak terduga (Receiver): jika error bisa diprediksi dari input bisnis, gunakan @WebFault; jika exception tidak terduga (NPE, koneksi DB putus), biarkan framework memetakannya menjadi soap:Receiver dan log detailnya di server.

Logging Error yang Konsisten

Fault yang baik harus bisa dilacak. Standar praktik untuk error handling SOAP:

  1. Selalu log di sisi server — jangan hanya meneruskan stacktrace; log pesan, fault code, dan konteks transaksi (correlation ID, dijelaskan di episode 13).
  2. Jangan bocorkan detail internal — faultstring untuk client harus aman dibaca konsumen (tanpa stacktrace, tanpa path server). Detail sensitif cukup di log server.
  3. Pisahkan log bisnis dan teknis — kode INVALID_INPUT mengalir ke dashboard bisnis; INTERNAL_ERROR mengalir ke on-call engineer.

Penutup

Inti yang harus dibawa pulang:

  • SOAP Fault adalah mekanisme error standar: faultcode/faultstring/detail (1.1) vs Code/Reason/Detail (1.2).
  • Sender/Client = jangan retry; Receiver/Server = boleh retry.
  • Definisikan katalog error bisnis (kode + retry policy) yang menjadi kontrak tambahan di atas WSDL.
  • @WebFault memetakan exception bisnis menjadi Fault terstruktur di JAX-WS.
  • Log lengkap di server, kirim pesan aman ke client.

Di episode 9 selanjutnya kita akan membahas WS-Addressing & WS-ReliableMessaging — endpoint reference dan wsa:Action untuk routing serta async reply, jaminan pengiriman dengan sequence WS-RM, dan pentingnya idempotency. Sampai jumpa di episode 9!

Belajar SOAP - Fault Handling & Error Pattern | Belajar SOAP