Skip to content

Error Codes

ICOSYS uses a global IC-* error code system. Every error response includes a structured JSON body with a machine-readable code, a human-readable message, and a correlation ID for log tracing.


Error Response Format

All backend errors return this consistent JSON structure:

Error Response
{
  "status": "ERROR",
  "error_code": "IC-BPM-4001",
  "message": "Business partner not found",
  "ref_id": "a3f8b2c9",
  "http_status": 404,
  "timestamp": "2026-02-15T10:30:00Z",
  "path": "/api/business-partner/999"
}
Field Type Description
status string Always "ERROR"
error_code string IC-* code (see registry below)
message string Localized message (EN/TR based on Accept-Language)
ref_id string 8-character correlation ID for log lookup
http_status int HTTP status code
timestamp string ISO-8601 timestamp
path string Request URI

Log Correlation

Use ref_id to find the full stack trace in exception logs:

GET /icglb/services/api/logs/exceptions/a3f8b2c9

Error Code Format

IC-{MODULE}-{CATEGORY}{SEQUENCE}
Part Values Description
IC Fixed prefix ICOSYS platform
MODULE SYS, BPM, DMS Source module
CATEGORY 1xxx6xxx Error category (see below)
SEQUENCE 001999 Unique within category

Categories

Range Category Description
1xxx Authentication Login, session, token errors
2xxx Validation Field required, business rule violations
3xxx API / Network Service unavailable, timeouts, not found
4xxx Data / CRUD Entity not found, version conflict, references
5xxx File / Storage Upload validation, storage failures (DMS only)
6xxx System Unexpected errors, parse errors

IC-SYS — System Errors

Platform-wide errors that apply to all services.

Authentication (1xxx)

Code HTTP Severity Description
IC-SYS-1001 401 error Session expired — token is no longer valid
IC-SYS-1002 403 error Access denied — insufficient permissions
IC-SYS-1003 401 error Invalid token — malformed or tampered JWT

Validation (2xxx)

Code HTTP Severity Description
IC-SYS-2001 400 warn Required field is missing or blank
IC-SYS-2002 400 warn Generic validation error

API / Network (3xxx)

Code HTTP Severity Description
IC-SYS-3001 503 error Service unavailable
IC-SYS-3002 504 error Request timeout
IC-SYS-3003 404 warn Resource not found
IC-SYS-3004 405 warn HTTP method not allowed
IC-SYS-3005 415 warn Media type not supported

Data / CRUD (4xxx)

Code HTTP Severity Description
IC-SYS-4001 404 error Entity not found by ID
IC-SYS-4002 409 error Version conflict — record modified by another user
IC-SYS-4003 409 error Cannot delete — record is referenced by other data

System (6xxx)

Code HTTP Severity Description
IC-SYS-6001 500 error Unexpected internal error
IC-SYS-6002 400 warn JSON parse error — malformed request body

IC-BPM — Business Partner Management

Validation (2xxx)

Code HTTP Severity Description
IC-BPM-2001 400 warn Required field is missing
IC-BPM-2002 409 warn Tax number already exists for this tenant
IC-BPM-2003 409 warn Branch name already exists for this partner
IC-BPM-2004 400 warn Contract dates are invalid (end before start)
IC-BPM-2005 400 warn Partner must be marked as customer or vendor
IC-BPM-2006 409 warn Default branch already exists for this partner
IC-BPM-2007 409 warn Primary contact already exists for this partner
IC-BPM-2008 409 warn Accrual period already exists (duplicate period)
IC-BPM-2009 400 warn Accrual cannot be updated in current status
IC-BPM-2010 400 warn Accrual cannot be deleted in current status
IC-BPM-2011 400 warn Accrual cannot be approved in current status
IC-BPM-2012 400 warn Accrual cannot be invoiced in current status
IC-BPM-2013 400 warn Accrual cannot be cancelled in current status
IC-BPM-2014 400 error Invalid tenant — crProcessId not found

Data (4xxx)

Code HTTP Severity Description
IC-BPM-4001 404 error Entity not found

IC-DMS — Document Management

Validation (2xxx)

Code HTTP Severity Description
IC-DMS-2001 409 warn Category name already exists in this tenant
IC-DMS-2002 400 warn Category circular reference detected
IC-DMS-2003 400 warn Category has child categories — delete children first
IC-DMS-2004 410 warn Share link has expired
IC-DMS-2005 401 warn Share link requires a password
IC-DMS-2006 401 warn Share link password is incorrect
IC-DMS-2007 410 warn Signed download URL has expired
IC-DMS-2008 403 error Signed download URL is invalid (tampered)
IC-DMS-2009 409 warn Account config already exists for this tenant
IC-DMS-2010 410 warn Share link is inactive
IC-DMS-2011 429 warn Share link download limit reached

Data (4xxx)

Code HTTP Severity Description
IC-DMS-4001 404 error File not found
IC-DMS-4002 404 error Category not found
IC-DMS-4003 404 error Share link not found

File / Storage (5xxx)

Code HTTP Severity Description
IC-DMS-5001 400 warn Uploaded file is empty
IC-DMS-5002 413 warn File exceeds maximum allowed size
IC-DMS-5003 415 warn File extension is not in the allowed list
IC-DMS-5004 415 error Dangerous file extension detected (e.g., .exe, .bat)
IC-DMS-5005 415 error File magic number does not match declared extension
IC-DMS-5006 403 error Path traversal attempt detected in filename
IC-DMS-5007 500 error File storage operation failed
IC-DMS-5008 413 warn Storage quota exceeded for this tenant
IC-DMS-5009 400 warn Invalid file name (illegal characters)
IC-DMS-5010 500 error File read operation failed
IC-DMS-5011 500 error File store operation failed
IC-DMS-5012 500 error File checksum verification failed
IC-DMS-5013 404 error Physical file not found on storage
IC-DMS-5014 500 error File retrieval from storage failed
IC-DMS-5015 500 error Signed URL computation failed

HTTP Status Code Mapping

When the backend returns a plain HTTP error without an IC-* code, the frontend maps the status to a default code:

HTTP Status Default IC Code Description
400 IC-SYS-2002 Bad request / validation error
401 IC-SYS-1001 Unauthorized / session expired
403 IC-SYS-1002 Forbidden / access denied
404 IC-SYS-3003 Resource not found
409 IC-SYS-4002 Conflict / version mismatch
413 IC-DMS-5002 Payload too large
415 IC-SYS-3005 Unsupported media type
429 Rate limited (Retry-After header)
500 IC-SYS-6001 Internal server error
502 / 503 IC-SYS-3001 Service unavailable
504 IC-SYS-3002 Gateway timeout

Backend Exception Handling

GlobalExceptionHandler

All services use a shared GlobalExceptionHandler (@ControllerAdvice) that:

  1. Catches every exception (including Spring framework exceptions)
  2. Generates an 8-character refId for correlation
  3. Logs the full exception to the database (s_exception_log table)
  4. Returns the structured error JSON response
  5. Resolves message language from Accept-Language header
Flow (simplified)
ServiceException("IC-BPM-2002", "Tax number exists")
     GlobalExceptionHandler.handleServiceException()
     Generate refId: "a3f8b2c9"
     Log to DB: refId, stackTrace, requestInfo, user
     Return: { error_code, message, ref_id, http_status, ... }

ServiceException

All business logic errors throw ServiceException with an IC-* code:

throw new ServiceException(ErrorCodes.BPM_TAX_NUMBER_EXISTS, "Tax number exists");

Exception Log Entry

Each logged exception contains:

Field Description
refId 8-character correlation ID (returned to client)
logUuid Full UUID for internal reference
errorCode IC-* code
message Exception message
stackTrace Full Java stack trace
requestUri Request URL
requestParams Query parameters
httpMethod GET, POST, PUT, DELETE
userCode Authenticated user (from JWT)
ipAddress Client IP
userAgent Browser/client identifier
severity ERROR, WARN, INFO
createdAt Timestamp

Frontend Error Handling

Error Flow

API call fails
Axios interceptor
    ├─ 401 → Clear session → Redirect /login
    └─ Other → Parse response body
              ApiError class
              { errorCode, refId, httpStatus, userMessage }
          handleApiError()
              ├─ Lookup IC-* code in frontend registry
              ├─ Get localized message (TR/EN)
              └─ Show toast notification

ApiError Class

api-error.ts
class ApiError {
  errorCode: string    // "IC-BPM-4001"
  refId: string        // "a3f8b2c9"
  httpStatus: number   // 404
  userMessage: string  // Localized message from backend
}

Error Code Registry (Frontend)

The frontend maintains a parallel registry of all IC-* codes with bilingual messages:

error-codes.ts (example entries)
{
  "IC-SYS-4002": {
    severity: "error",
    category: "data",
    en: "This record was modified by another user. Please refresh and try again.",
    tr: "Bu kayıt başka bir kullanıcı tarafından değiştirildi. Lütfen yenileyip tekrar deneyin."
  },
  "IC-DMS-5002": {
    severity: "warn",
    category: "file",
    en: "File exceeds maximum allowed size.",
    tr: "Dosya izin verilen maksimum boyutu aşıyor."
  }
}

Toast Display

Usage in components
try {
  await service.create(data)
} catch (error) {
  handleApiError(error)
  // Shows toast: "[IC-BPM-2002] Bu vergi numarası zaten kullanılıyor. (ref: a3f8b2c9)"
}
Severity Toast Type Duration
error Red error toast 8 seconds
warn Yellow warning toast 5 seconds
info Blue info toast 3 seconds

Error Display Message

For inline error banners (e.g., form validation):

const message = getErrorDisplayMessage(error)
// Returns: "IC-BPM-4001 - Business partner not found (ref: a3f8b2c9)"

Common Error Scenarios

Optimistic Lock Failure

User A loads record (version: 3)
User B loads record (version: 3)
User A saves → success (version: 4)
User B saves → 409 Conflict, IC-SYS-4002
409 Conflict
{
  "error_code": "IC-SYS-4002",
  "message": "This record was modified by another user. Please refresh and try again.",
  "ref_id": "d4e5f6a7"
}

Frontend shows an error toast with a "Reload" button.

Referential Integrity Violation

409 Conflict
{
  "error_code": "IC-SYS-4003",
  "message": "Cannot delete: This record is referenced by other data.",
  "ref_id": "e5f6a7b8"
}

File Upload Rejection

415 Unsupported Media Type
{
  "error_code": "IC-DMS-5005",
  "message": "File magic number does not match the declared extension.",
  "ref_id": "f6a7b8c9"
}

This catches files where the extension has been renamed (e.g., .exe renamed to .pdf).

Rate Limit Exceeded

429 Too Many Requests
{
  "status": 429,
  "message": "Rate limit exceeded. Maximum 200 requests per minute allowed.",
  "retryAfter": 60
}

Adding New Error Codes

Backend

  1. Add the constant to ErrorCodes.java (or module-specific ServiceErrorMsgCodes):

    ErrorCodes.java
    public static final String HRM_EMPLOYEE_EMAIL_EXISTS = "IC-HRM-2001";
    
  2. Add messages to messages.properties and messages_tr.properties:

    messages.properties
    IC-HRM-2001=Employee email already exists
    
    messages_tr.properties
    IC-HRM-2001=Çalışan e-posta adresi zaten mevcut
    
  3. Throw in service code:

    throw new ServiceException(ErrorCodes.HRM_EMPLOYEE_EMAIL_EXISTS);
    

Frontend

Add the code to the frontend registry:

error-codes.ts
"IC-HRM-2001": {
  severity: "warn",
  category: "validation",
  en: "Employee email already exists.",
  tr: "Çalışan e-posta adresi zaten mevcut."
}

What's Next?

  • REST API — Full endpoint reference for all services
  • Authentication — JWT flow, API keys, security filters