drogon icon indicating copy to clipboard operation
drogon copied to clipboard

Failing gracefully on exception from controller construction

Open timomrs opened this issue 2 years ago • 3 comments

When a constructor of an HttpController throws, and the exception propagates through drogon::app().run() to main() and is caught there, it appears impossible to exit the program gracefully, since the assert on trantor/net/EventLoop.cc:115 in EventLoop::~Eventloop() triggers on exit. Looking at the source code, it appears that there is no easy workaround, since looping_ in the trantor event loop is not handled exception safely.

My use case for throwing in the constructor of a controller is that there are some settings (currently loaded from config.json) which, if misconfigured, may prevent the service from doing its work at all. In that case, I believe it's better for the service to exit on startup and let the admin know to fix the configuration, rather than running a non-functional service.

There should be a way to exit gracefully when exceptions are thrown in controller constructors.

timomrs avatar Jan 13 '22 10:01 timomrs

This is probably related to https://github.com/an-tao/trantor/pull/198

rbugajewski avatar Jan 27 '22 11:01 rbugajewski

@rbugajewski I think you're right. If I understood the code in https://github.com/an-tao/trantor/pull/198 correctly, that pull request would actually change the assert failure in to a hang in EventLoop::~EventLoop(), which is obviously even worse.

I think a minimal change to make this work in Trantor would be to use a scope guard (for example, https://github.com/ricab/scope_guard seems reasonable, though I haven't tried it myself) to set _looping to false when the EventLoop::looping() scope is exited via any path. I think this would be best practice anyway?

timomrs avatar Jan 28 '22 07:01 timomrs

PR 224 in trantor implements a partial fix (changes hang to exit via assert).

timomrs avatar Sep 06 '22 10:09 timomrs