This is handled in the `chronos` http server like so: <https://github.com/status-im/nim-chronos/blob/master/chronos/apps/http/httpserver.nim#L597-L606>
In general, `asyncCheck` is a construct that we've deprecated because there's no way it can sanely work - it raises exceptions through the poll loop where they cannot reasonably be handled. We've replaced it with `asyncSpawn` where it is understood that any "independent" tasks must also catch the exceptions that are raised within so as to be fully independent. In order to make this work, we also ensure (with raises constraints) that no "naked" callbacks raise - this means that `poll` can assume that anything it calls doesn't raise which drastically simplifies reasoning about correctness - `async` functions in particular never (directly) raise: they catch all exceptions transport them on the future - all other callbacks must clean up after themselves.