Error Handling
The library maps PHP exceptions to OData-compliant error responses.
Error response format
All errors follow the OData error format:
json
{
"error": {
"code": "not_found",
"message": "Entity with key 'id=999' not found in 'Products'.",
"target": "Products(999)"
}
}Exception hierarchy
All protocol exceptions extend ProtocolException:
| Exception | HTTP Status | OData Code | When thrown |
|---|---|---|---|
BadRequestException | 400 | bad_request | Malformed query options, invalid filter syntax, unknown properties |
NotFoundException | 404 | not_found | Entity not found, unknown entity set |
NotImplementedException | 501 | not_implemented | Unsupported operations ($apply, write verbs, missing EntityResolverInterface) |
InternalServerErrorException | 500 | internal_server_error | Unexpected server errors |
Building error responses
Exceptions use a fluent API:
php
use LaravelUi5\OData\Exception\NotFoundException;
throw (new NotFoundException())
->code('entity_not_found')
->message("Product with id=42 not found.")
->target('Products(42)');Adding details
php
throw (new BadRequestException())
->code('invalid_filter')
->message('The $filter expression is invalid.')
->addDetail('syntax_error', 'Unexpected token at position 15', '$filter')
->addInnerError('expression', "name eq 'Widget' and");Produces:
json
{
"error": {
"code": "invalid_filter",
"message": "The $filter expression is invalid.",
"details": [
{"code": "syntax_error", "message": "Unexpected token at position 15", "target": "$filter"}
],
"innererror": {
"expression": "name eq 'Widget' and"
}
}
}Streaming error handling
When streaming is enabled in config (default), errors that occur mid-stream (after HTTP headers have been sent) are handled via HTTP trailers:
- The response starts streaming with HTTP 200
- If an exception occurs while yielding rows, the stream is terminated
- An
odata-errortrailer is appended with the error JSON
When streaming is disabled, the entire response is buffered. If an exception occurs, the buffer is discarded and a proper error response with the correct HTTP status code is sent.
Custom error responses
You can add custom headers to error responses:
php
throw (new BadRequestException())
->message('Rate limit exceeded')
->header('Retry-After', '60');