Search code examples
groovyvert.x

vert.x: Register failureHandler to all routes


In my app I have routes like:

router.get "/api/$name/:id" handler this.&details
router.post "/api/$name" consumes JSON produces JSON handler this.&save
router.delete "/api/$name/:id" handler this.&delete
// a lot more of those

I want to register a failureHandler to all of those routes, to do simple error logging like:

void handleError( RoutingContext rc ) {
    Throwable failure = rc.failure()
    log.error failure.message, failure
    rc.response().setStatusCode 500 putHeader 'content-type', JSON end """{ "message":"$failure.message"}"""
}

The doc shows, that I can register the failureHandler on per-route basis like so:

router.get "/api/$name/:id" handler this.&details failureHander this.&handleError

which would become pretty verbose and self-repeating very soon.

I tried to register a handler on a wildcard path:

router.route '/*' failureHandler this.&handleError

but that is ignored.

Is there a way to register a global failureHandler?


Solution

  • It turns out to be fairly straight-forward. I was misguided by the FailureHandler registered in one of the super-classes.

    The final code looks like this:

    router.route().with{
      handler BodyHandler.create() 
      handler ResponseContentTypeHandler.create()
      handler FaviconHandler.create( 'webroot/favicon.ico' )
    
      failureHandler{ rc -> 
        log.error 'Error occured', rc.failure()
        rc.next()
      }
      failureHandler ErrorHandler.create( WebEnvironment.development() )
    }
    

    Herewith I define a chain of failure-handlers, the 1st of which logs the exception off, and delegates to the Vert.x' handler to render a nice response.

    Hope it can help someone to save days of reverse-engineering :)