Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

The sane thing to do is to let lower layer functions return

    Either<Error, Foo>
then, in the HTTP layer, your endpoint code just looks like

    return fooService
                .getFoo(
                    fooId
                ) //Either<Error, Foo>
                .fold({ //left (error) case
                    when (it) {
                        is GetFooErrors.NotAuthenticated -> { Response.status(401).build() }
                        is GetFooErrors.InalidFooId -> { Response.status(400).build() }
                        is GetFooErrors.Other -> { Response.status(500).build() }
                    }
                }, { //right case
                   Response.ok(it)
                })
the benefits of this are hard to overstate.

* Errors are clearly enumerated in a single place. * Errors are clearly separated from but connected to HTTP, in the appropriate layer. (=the HTTP layer) Developers can tell from a glance at the resource method what the endpoint will return for each outcome, in context. * Errors are guaranteed to be exhaustively mapped because Kotlin enforces that sealed classes are exhaustively mapped at compile time. So a 500 resulting from forgetting to catch a ReusedPasswordException is impossible, and if new errors are added without being mapped to HTTP responses, the compiler will let us know.

It beats exceptions, it beats Go's shitty error handling.



Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: