Errors
Most controller actions return a JSON envelope produced by ApiResponseFactory rather than raw ASP.NET Problem Details.
Success envelope
<pre><code class="language-json">{ "isSuccess": true, "message": "Contract has been saved successfully.", "entity": { }, "error": null }
Validation / domain error envelope
<pre><code class="language-json">{ "isSuccess": false, "message": "Invalid contract data.", "entity": "Invalid contract data.", "error": { "code": "...", "message": "..." } }
Typical HTTP status mapping:
| HTTP status | When |
|---|---|
400 Bad Request | Invalid body, model state, or domain validation (InvalidDateException, ArgumentException, …) |
401 Unauthorized | Missing or invalid Bearer token |
403 Forbidden | Authenticated but missing screen permission, or inactive employee |
404 Not Found | Resource missing (ApiResponseFactory.NotFound) |
500 Internal Server Error | Unexpected failures (ApiResponseFactory.ServerError) |
Framework and EF exception text is scrubbed in ServerError responses so clients see a stable unexpected-error message instead of inner exception details.
Inactive employee middleware
PlatformAccessExceptionMiddleware catches InactiveEmployeeException after authentication and returns:
- - Status:
403 Forbidden - - Body:
ApiResponseFactory.ValidationError<object>(ex.Message)
The portal shows an inactive-account message for this case.
Auth failure summary (portal behaviour)
| Scenario | Backend | Portal |
|---|---|---|
| No token | 401 | Redirect to /login |
| Valid token, no employee | Auto-provisions employee | Continues with /Employee/Me |
| Inactive employee | 403 + message | Inactive account UI |
| Missing screen permission | 403 | Permission denied UI |