From be69b76ce260ca41204d8353351e42faf3a6748d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6nke=20Ludwig?= Date: Mon, 1 Apr 2024 16:17:41 +0200 Subject: [PATCH] Ensure uncaught throwables in task fibers are visible to the user. Prefers logFatal over stderr.writeln so that the error also ends up in log files that may be configured. Also displays a message box for subsystem "windows" executables that don't have a console attached. --- dub.sdl | 2 +- source/vibe/core/task.d | 31 +++++++++++++++++++++++++++---- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/dub.sdl b/dub.sdl index 96c81972..b6210bed 100644 --- a/dub.sdl +++ b/dub.sdl @@ -5,7 +5,7 @@ copyright "Copyright © 2016-2020, Sönke Ludwig" license "MIT" dependency "eventcore" version="~>0.9.27" -dependency "vibe-container" version=">=1.1.0 <2.0.0-0" +dependency "vibe-container" version=">=1.3.1 <2.0.0-0" targetName "vibe_core" diff --git a/source/vibe/core/task.d b/source/vibe/core/task.d index 6212b1df..b35a5e75 100644 --- a/source/vibe/core/task.d +++ b/source/vibe/core/task.d @@ -412,12 +412,35 @@ final package class TaskFiber : Fiber { } catch (Throwable th) { import std.stdio : stderr, writeln; import core.stdc.stdlib : abort; + import core.memory : GC; try { - stderr.writeln("TaskFiber getting terminated due to an uncaught ", th.classinfo.name); - stderr.writeln(th); + version (Windows) { + import core.sys.windows.windows : MessageBoxA, MB_ICONERROR, GetConsoleWindow; + import std.format : formattedWrite; + import vibe.container.internal.appender : BufferOverflowMode, FixedAppender; + + if (!GetConsoleWindow()) { + FixedAppender!(char[], 2048, BufferOverflowMode.ignore) msg = void; + msg.formattedWrite("%s: %s\r\n\r\n", th.classinfo.name, th.msg); + foreach (ln; th.info) + msg.formattedWrite("%s\r\n", ln); + msg.put('\0'); + msg.data[msg.data.length-1] = '\0'; + MessageBoxA(null, msg.data.ptr, "FATAL: Uncaught exception in task fiber", MB_ICONERROR); + } + } + if (GC.inFinalizer) { + stderr.writeln("TaskFiber getting terminated due to an uncaught ", th.classinfo.name, ": ", th.msg); + foreach (ln; th.info) stderr.writeln(ln); + } else { + logFatal("TaskFiber getting terminated due to an uncaught %s: %s", th.classinfo.name, th.msg); + foreach (ln; th.info) logFatal("%s", ln); + } } catch (Exception e) { - try stderr.writeln(th.msg); - catch (Exception e) {} + if (GC.inFinalizer) { + try stderr.writeln(th.msg); + catch (Exception e) {} + } else logFatal("%s", th.msg); } abort(); }