1

In my Dropwizard project, I'm defining a generic ExceptionMapper<WebApplicationException>:

environment.jersey().register(new WebApplicationExceptionMapper());

...but this doesn't seem to catch any of the 404 errors for unmatched paths.

Without defining five defaultHandler() methods for every single resource, how do I catch all 404s so I can return my own error page or some JSON?

So, if I had a service with one resrouce, say, /docs, this is the situtation:

  • /myservice/docs/helloworld doesn't match any @Path defined in my DocsResource. It returns a generic Jetty 404 page (not what I want)

  • /myservice/doesntexist returns my own error resource with the exception mapper (this is what I want everywhere)

pandaadb
  • 6,306
  • 2
  • 22
  • 41
Stefano Palazzo
  • 4,212
  • 2
  • 29
  • 40
  • Try NotFoundException – Paul Samsotha Apr 04 '16 at 11:53
  • Doesn't work unfortunately. They are caught by the WebApplicationException mapper too. In fact, if I catch `Exception` here, I get nothing at all for unmatched paths in a resource, as if they are handled within the Jetty bit of the application, and never get to the Jersey layer. If that makes sense. – Stefano Palazzo Apr 04 '16 at 12:13
  • [Try this](http://stackoverflow.com/a/34321347/2587435) – Paul Samsotha Apr 04 '16 at 12:16

1 Answers1

2

what you need to do is to set a different Error handler. The 404's you are seeing when hitting a non-existing path, are not handled by jersey. Jersey maps exceptions for resources, but you in fact never hit the resource in the first place. This is where you will need to define an error handler:

In DefaultServerFactory, you need to overwrite:

protected Server buildServer(LifecycleEnvironment lifecycle,
                                 ThreadPool threadPool) {
        final Server server = new Server(threadPool);
        server.addLifeCycleListener(buildSetUIDListener());
        lifecycle.attach(server);
        final ErrorHandler errorHandler = new ErrorHandler();
        errorHandler.setServer(server);
        errorHandler.setShowStacks(false);
        server.addBean(errorHandler);
        server.setStopAtShutdown(true);
        server.setStopTimeout(shutdownGracePeriod.toMilliseconds());
        return server;
    }

(This class is in AbstractServerFactory).

You then can implement your own ErrorHandler and make it do whatever it is you want it to do.

For testing, open org.eclipse.jetty.server.handler.ErrorHandler and set a breakpoint, then try and hit a non-existing URL. It will stop there and you can see how jetty handles this sort of thing.

I hope that helps.

If you need help overwriting default DW functionality, you can look at a similar post where I described how to overwrite loggers:

Dropwizard doesn't log custom loggers to file

Cheers, Artur

Community
  • 1
  • 1
pandaadb
  • 6,306
  • 2
  • 22
  • 41