///////////////////////////////////////////////////////////////////////////////

    Copyright (c) 2018 Oracle and/or its affiliates. All rights reserved.

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

        http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.

///////////////////////////////////////////////////////////////////////////////

= Error Handling
:description: Helidon Reactive WebServer error handling
:keywords: helidon, reactive, reactive streams, reactive java, reactive webserver

== Error Routing

You may register an error handler for a specific `Throwable` in the
 `Routing.Builder` method.
[source,java]
----
Routing routing = Routing.builder()
                        .error(MyException.class, (req, res, ex) -> { // <1>
                            // handle the error, set the HTTP status code
                            res.send(errorDescriptionObject); // <2>
                        })
                        .build
----
<1> Registers an error handler that handles `MyException` that are thrown from the
 upstream handlers
<2> Finishes the request handling by sending a response

Error handlers are called when

* an exception is thrown from a handler
* `req.next(ex)` is called, where `ex` is an instance of `Throwable`

As with the standard handlers, the error handler must either

* send a response
+
[source,java]
----
.error(MyException.class, (req, res, ex) -> {
    res.status(Http.Status.BAD_REQUEST_400);
    res.send("Unable to parse request. Message: " + ex.getMessage());
})
----
* or, forward the error handling to the downstream error handlers
+
[source,java]
----
.error(Throwable.class, (req, res, ex) -> {
    // some logic
    req.next(ex);
})
----

Error handling can't be forwarded to the standard
 handlers. In fact, invoking `req.next(ex)` or `req.next()` in an error handler 
 are equivalent. 

[source,java]
----
.error(Throwable.class, (req, res, ex) -> {
    if (condition) {
        req.next(ex); // <1>
    } else {
        req.next(); // <2>
    }
})
----
<1> Call a downstream error handler with the `Throwable` instance.
<2> Here, `req.next()` is the same as `req.next(ex)`. In both cases, the downstream error handler is called.


=== Default error handling
If no user-defined error handler is matched, or if the last error handler of the
exception called `req.next()`, then the exception is translated to an HTTP response as follows:

 * Subtypes of `HttpException` are translated to their associated HTTP error codes.
+
[source,java]
.Reply with the `406` HTTP error code by throwing an exception
----
(req, res) -> throw new HttpException("Amount of money must be greater than 0.", Http.Status.NOT_ACCEPTABLE_406) // <1>
----

 * Otherwise, the exceptions are translated to an Internal Server Error HTTP
 error code `500`.


== Registering an application - Organizing code into services

You can also register an application that has its own handlers at a path prefix or context root.
[source,java]
.Registering routing logic for a context root
----
.register("/context-root", new MyComplexApplication())
----

[source,java]
.Routing logic implementation
----
public class MyComplexApplication implements Consumer<Routing.Config> {
    @Override
    public void accept(Routing.Config config) {
        config.get("/subpath", (req, res) -> {/* handler */});
    }
}
----
In this example, the `GET` handler matches requests to `/context-root/subpath`.
