Skip to Content
MemulaiError Handling

Error Handling

Fumai Mobile API menggunakan kode status HTTP standar dan menyertakan error code di response body.

HTTP Status Codes

Status CodeKeterangan
200OK — Request berhasil
201Created — Resource berhasil dibuat
400Bad Request — Validasi gagal
401Unauthorized — Token tidak valid atau tidak disertakan
403Forbidden — Tidak memiliki akses
404Not Found — Resource tidak ditemukan
409Conflict — Data duplikat atau konflik
429Too Many Requests — Rate limit terlampaui
500Internal Server Error — Kesalahan server

Error Codes

Error CodeHTTP StatusKeteranganAksi di Client
UNAUTHORIZED401Token tidak adaRedirect ke login
INVALID_ACCESS_TOKEN401Access token expired/invalidPanggil /auth/refresh
INVALID_CREDENTIALS401Email atau password salahTampilkan field error
GOOGLE_ACCOUNT401User terdaftar via GoogleArahkan ke Google Sign In
EMAIL_NOT_VERIFIED403Email belum diverifikasiArahkan ke verify step
INVALID_REFRESH_TOKEN401Refresh token invalid/expiredRedirect ke login
REFRESH_FAILED401Gagal memperbarui tokenRedirect ke login
VALIDATION_ERROR400Input tidak validTampilkan field errors
INVALID_EMAIL400Format email tidak validTampilkan field error
EMAIL_EXISTS409Email sudah terdaftarArahkan ke login
INVALID_CODE400OTP code salah/expiredTampilkan error, sarankan resend
EMAIL_FAILED500Gagal mengirim emailRetry nanti
USER_NOT_FOUND404User tidak adaRedirect ke login
INVALID_GOOGLE_TOKEN401Google token invalidRetry Google sign-in
GOOGLE_EMAIL_NOT_VERIFIED401Email Google belum verifiedTampilkan error
INVALID_APPLE_TOKEN401Apple token invalidRetry Apple sign-in
APPLE_EMAIL_REQUIRED400Email tidak tersedia dari AppleUser harus berikan izin email
ACCOUNT_NOT_VERIFIED401Email belum verified (OAuth linking)Tampilkan prompt verifikasi
PASSWORD_ALREADY_SET409User sudah punya passwordArahkan ke change password
INVALID_TOKEN400Reset token invalid/expiredTampilkan error, resend link
INVALID_FILE_TYPE400File bukan imageTampilkan error
FILE_TOO_LARGE400File lebih dari 5MBTampilkan error
SUBSCRIPTION_REQUIRED403Fitur premiumTampilkan upgrade prompt
RATE_LIMITED429Terlalu banyak requestRetry setelah delay
SERVER_ERROR500Internal server errorRetry atau tampilkan error

Contoh Penanganan Error

async function callAPI(endpoint, options = {}) { const res = await fetch(`https://fumai.app/api/mobile/v1${endpoint}`, { headers: { Authorization: `Bearer ${accessToken}`, 'Content-Type': 'application/json', }, ...options, }) const result = await res.json() if (!result.success) { switch (result.code) { case 'INVALID_ACCESS_TOKEN': // Token expired, coba refresh await refreshAccessToken() return callAPI(endpoint, options) case 'RATE_LIMITED': // Tunggu sebelum retry const retryAfter = res.headers.get('Retry-After') await sleep(retryAfter * 1000) return callAPI(endpoint, options) case 'VALIDATION_ERROR': console.error('Validasi gagal:', result.error) break default: console.error('API Error:', result.code, result.error) } throw new Error(result.error) } return result }

Rate Limits

EndpointLimitWindow
Check Email101 menit
Login51 menit
Register31 jam
Google OAuth1015 menit
Apple Sign In1015 menit
Verify Email1015 menit
Resend Verification25 menit
Forgot Password31 jam
Reset Password515 menit
Report Issue31 jam
Sessions31 jam
Set Initial Password31 jam
Refresh Token301 menit
General API1001 menit

Response header saat rate limited:

X-RateLimit-Limit: 100 X-RateLimit-Remaining: 0 Retry-After: 30

Retry Strategy

Info: Untuk error 429 (Rate Limit) dan 5xx (Server Error), disarankan menggunakan exponential backoff untuk retry.

async function fetchWithRetry(url, options, maxRetries = 3) { for (let attempt = 0; attempt < maxRetries; attempt++) { const res = await fetch(url, options) if (res.ok) return res.json() if (res.status === 429 || res.status >= 500) { const delay = Math.pow(2, attempt) * 1000 await new Promise(resolve => setTimeout(resolve, delay)) continue } return res.json() } throw new Error('Max retries exceeded') }
Last updated on