Skip to content

Commit ff78fd0

Browse files
committed
Improve documentation for error handling
1 parent 89793e5 commit ff78fd0

1 file changed

Lines changed: 52 additions & 39 deletions

File tree

README.md

Lines changed: 52 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,14 @@ Event-driven, streaming plaintext HTTP and secure HTTPS server for [ReactPHP](ht
1111
* [Server](#server)
1212
* [StreamingServer](#streamingserver)
1313
* [listen()](#listen)
14-
* [error event](#error-event)
1514
* [Request](#request)
1615
* [Request parameters](#request-parameters)
1716
* [Query parameters](#query-parameters)
1817
* [Request body](#request-body)
1918
* [Streaming request](#streaming-request)
2019
* [Request method](#request-method)
2120
* [Cookie parameters](#cookie-parameters)
21+
* [Invalid request](#invalid-request)
2222
* [Response](#response)
2323
* [Deferred response](#deferred-response)
2424
* [Streaming response](#streaming-response)
@@ -266,41 +266,6 @@ $server->listen($socket);
266266

267267
See also [example #11](examples) for more details.
268268

269-
### error event
270-
271-
The `StreamingServer` supports both HTTP/1.1 and HTTP/1.0 request messages.
272-
If a client sends an invalid request message, uses an invalid HTTP protocol
273-
version or sends an invalid `Transfer-Encoding` in the request header, it will
274-
emit an `error` event, send an HTTP error response to the client and
275-
close the connection:
276-
277-
```php
278-
$server->on('error', function (Exception $e) {
279-
echo 'Error: ' . $e->getMessage() . PHP_EOL;
280-
});
281-
```
282-
283-
The server will also emit an `error` event if you return an invalid
284-
type in the callback function or have a unhandled `Exception` or `Throwable`.
285-
If your callback function throws an `Exception` or `Throwable`,
286-
the `StreamingServer` will emit a `RuntimeException` and add the thrown exception
287-
as previous:
288-
289-
```php
290-
$server->on('error', function (Exception $e) {
291-
echo 'Error: ' . $e->getMessage() . PHP_EOL;
292-
if ($e->getPrevious() !== null) {
293-
$previousException = $e->getPrevious();
294-
echo $previousException->getMessage() . PHP_EOL;
295-
}
296-
});
297-
```
298-
299-
Note that the request object can also emit an error.
300-
Check out [request](#request) for more details.
301-
302-
> Note that any errors emitted by the wrapped `StreamingServer` are forwarded by `Server`.
303-
304269
### Request
305270

306271
As seen above, the [`Server`](#server) and [`StreamingServer`](#streamingserver)
@@ -727,6 +692,26 @@ This encoding is also used internally when decoding the name and value of cookie
727692

728693
See also [example #5](examples) for more details.
729694

695+
#### Invalid request
696+
697+
The `Server` and `StreamingServer` classes support both HTTP/1.1 and HTTP/1.0 request
698+
messages. If a client sends an invalid request message, uses an invalid HTTP
699+
protocol version or sends an invalid `Transfer-Encoding` request header value,
700+
the server will automatically send a `400` (Bad Request) HTTP error response
701+
to the client and close the connection.
702+
On top of this, it will emit an `error` event that can be used for logging
703+
purposes like this:
704+
705+
```php
706+
$server->on('error', function (Exception $e) {
707+
echo 'Error: ' . $e->getMessage() . PHP_EOL;
708+
});
709+
```
710+
711+
Note that the server will also emit an `error` event if you do not return a
712+
valid response object from your request handler function. See also
713+
[invalid response](#invalid-response) for more details.
714+
730715
### Response
731716

732717
The callback function passed to the constructor of the [`Server`](#server) or
@@ -950,9 +935,37 @@ to the message if the same request would have used an (unconditional) `GET`.
950935

951936
#### Invalid response
952937

953-
An invalid return value or an unhandled `Exception` or `Throwable` in the code
954-
of the callback function, will result in an `500 Internal Server Error` message.
955-
Make sure to catch `Exceptions` or `Throwables` to create own response messages.
938+
As stated above, each outgoing HTTP response is always represented by the
939+
[PSR-7 `ResponseInterface`](https://www.php-fig.org/psr/psr-7/#33-psrhttpmessageresponseinterface).
940+
If your request handler function returns an invalid value or throws an
941+
unhandled `Exception` or `Throwable`, the server will automatically send a `500`
942+
(Internal Server Error) HTTP error response to the client.
943+
On top of this, it will emit an `error` event that can be used for logging
944+
purposes like this:
945+
946+
```php
947+
$server->on('error', function (Exception $e) {
948+
echo 'Error: ' . $e->getMessage() . PHP_EOL;
949+
if ($e->getPrevious() !== null) {
950+
echo 'Previous: ' . $e->getPrevious()->getMessage() . PHP_EOL;
951+
}
952+
});
953+
```
954+
955+
Note that the server will also emit an `error` event if the client sends an
956+
invalid HTTP request that never reaches your request handler function. See
957+
also [invalid request](#invalid-request) for more details.
958+
Additionally, a [streaming request](#streaming-request) body can also emit
959+
an `error` event on the request body.
960+
961+
The server will only send a very generic `500` (Interval Server Error) HTTP
962+
error response without any further details to the client if an unhandled
963+
error occurs. While we understand this might make initial debugging harder,
964+
it also means that the server does not leak any application details or stack
965+
traces to the outside by default. It is usually recommended to catch any
966+
`Exception` or `Throwable` within your request handler function or alternatively
967+
use a [`middleware`](#middleware) to avoid this generic error handling and
968+
create your own HTTP response message instead.
956969

957970
#### Default response headers
958971

0 commit comments

Comments
 (0)