Replace throw kj::mv(*exception) with kj::throwRecoverableException(kj::mv(*exception)) in the async worker thread exception handler in type-context.h.
A raw throw creates a kj::Exception with the calling binary's typeinfo. On macOS with -fvisibility=hidden, this typeinfo is not coalesced with libkj.dylib's copy by the dynamic linker, so getCaughtExceptionAsKj()'s catch (kj::Exception& e) fails and falls through to catch (...), producing unknown non-KJ exception of type: kj::Exception errors.
throwFatalException() routes the throw through libkj, wrapping it in ExceptionImpl with consistent typeinfo. This matches the pattern KJ uses internally in kj/async-inl.h when re-throwing stored exceptions from promises.
Context: bitcoin/bitcoin#34723, bitcoin/bitcoin#35014