Mangcoding

icon chat
samsul aripin - Friday, 13 June 2025 - 11 months ago

Best Practices for Error Handling in the Backend

single image
Photo By Kostiantyn Li on Unsplash

Errors are bound to happen — whether due to incorrect user input, failed connections, or bugs that slipped through. The main issue isn’t the error itself, but how you handle it.

Note : The code examples in this article use PHP, but you can implement them in other programming languages as needed.

Here are best practices for error handling in the backend that you must apply :

Link Mangcoding

1. Handle Errors Properly — Don’t Let Them Pass Silently

⚠️ Don’t Silently Swallow Exceptions

Avoid writing code like this :

try {
    // sesuatu yang bisa gagal
} catch (Exception $e) {
    // sengaja dikosongkan 🙃
}

This makes the debugging process much more difficult. It’s better to log the error instead :

catch (Exception $e) {
    $logId = uniqid('pay_');

    Log::error('Gagal memproses pembayaran', [
        'log_id' => $logId,
        'user_id' => auth()->id(),
        'error' => $e->getMessage()
    ]);

    return response()->json([
        'status' => 'error',
        'message' => 'Terjadi kesalahan saat memproses pembayaran. Silakan coba lagi nanti.',
        'log_id' => $logId,
        'error_code' => 'PAYMENT_FAILED'
    ], 500);
}

Link Mangcoding

2. Use the Appropriate HTTP Status Code

Every error has its own specific code. Don’t return 200 OK when the data is not found. For example :

Situasi Kode yang Benar
 Data tidak ditemukan  404 Not Found
 Request tidak valid  400 Bad Request
 Gagal otorisasi  401 Unauthorized
 Error internal server  500 Internal Server Error

Link Mangcoding

3. Include an Error Code in the Response

In addition to the status code, add a specific error_code in the response. This makes it easier for frontend or mobile developers to handle it :

{
  "status": "error",
  "error_code": "PAYMENT_TIMEOUT",
  "message": "Pembayaran gagal karena timeout"
}

This way, the frontend can recognize that the PAYMENT_TIMEOUT error should trigger a specific UI.

Link Mangcoding

4. Provide a Fallback for Critical Flows

Some processes need to keep running even when an error occurs. For example :

  • Failed to send an email? Save it to a queue for retrying later.
  • Failed to save to Redis? Use the database as a fallback.
  • Payment error? Don’t cancel the order immediately mark it as “pending” instead.

Example :

try {
    // Coba kirim email 
    Mail::to($email)->send(new YourMailable());
} catch (Exception $err) {
    // Log error dan coba simpan ke antrean retry 
    Log::error('Gagal kirim email, akan dicoba ulang', ['err' => $err->getMessage()]);
    try {
        // Simpan ke antrean retry 
        saveToRetryQueue($emailData);
    } catch (Exception $fallback) {
        // Jika fallback gagal, log critical error 
        Log::critical('Gagal menyimpan ke antrean retry', ['err' => $fallback->getMessage()]);
    }
}

Link Mangcoding

4. Provide a Fallback for Critical Flows

By applying best practices for error handling in the backend, you’re not just preventing small errors from turning into disasters—you’re also making your system much more stable and developer-friendly.

Note: This article was inspired by a LinkedIn post by Mayank A. discussing best practices in software development. You can read the original version here.

Link Copied to Clipboard