From e215b777da7855700f3cae38e7c960fce152631c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 5 Aug 2026 00:39:23 +0000 Subject: [PATCH] fix: surface FSI evaluation errors to stderr by default in FsiEvaluator When a code snippet fails during --eval, the error was silently discarded unless the caller subscribed to the EvaluationFailed event or provided an onError callback. This made failures very hard to diagnose (e.g. native library loading failures in issue #685). Now a concise error message (file name + stderr output from FSI) is always written to stderr immediately, while the existing onError callback (used for --strict mode) continues to work as before. The misleading 'and --strict is on' phrase in the onError message has also been removed. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- RELEASE_NOTES.md | 3 +++ src/FSharp.Formatting.Literate/Evaluator.fs | 23 ++++++++++++++++++--- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index db104a87d..2d96d00c1 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -2,6 +2,9 @@ ## [Unreleased] +### Fixed +* Surface FSI evaluation failures to stderr by default in `FsiEvaluator`. Previously, when a code snippet failed during `--eval`, the error was silently discarded unless the caller subscribed to `EvaluationFailed` or provided an `onError` callback. Now a concise error message (file name + stderr output) is always written to stderr, making failures visible in `fsdocs` output. + ### Removed * Remove `docs/Dockerfile` (used for mybinder.org Binder integration) and mybinder badge links from documentation pages. The Binder integration relied on a deprecated .NET 7 SDK image and a deprecated `Microsoft.dotnet-interactive` version; mybinder.org support is discontinued. * Remove `.ipynb` (Jupyter Notebook) "run in notebook" badge links from all documentation pages and delete `docs/img/badge-notebook.svg`. The links linked to `.ipynb` outputs generated by fsdocs, but .NET Interactive (which powered those notebooks) is deprecated and has no current replacement. The `.ipynb` output format itself is unchanged. diff --git a/src/FSharp.Formatting.Literate/Evaluator.fs b/src/FSharp.Formatting.Literate/Evaluator.fs index 6b34f1a65..0b958129c 100644 --- a/src/FSharp.Formatting.Literate/Evaluator.fs +++ b/src/FSharp.Formatting.Literate/Evaluator.fs @@ -567,10 +567,27 @@ module __FsiSettings = Exception = e StdErr = e.Result.Error.Merged } - let msg = - $"Evaluation failed and --strict is on\n file=%A{file}\n asExpression=%b{asExpression}, text=%s{text}\n stdout=%s{e.Result.Output.Merged}\n\ stderr=%s{e.Result.Error.Merged}\n inner exception=%A{e.InnerException}" + // Always surface evaluation failures to stderr so they are visible by default, + // even when the caller has not subscribed to EvaluationFailed or provided onError. + let fileInfo = + match file with + | Some f -> $" in {f}" + | None -> "" - onError msg + let stderr = e.Result.Error.Merged.Trim() + + let errorMsg = + if stderr <> "" then + $"fsdocs eval: evaluation failure{fileInfo}\n{stderr}" + else + $"fsdocs eval: evaluation failure{fileInfo}\n{e.InnerException}" + + eprintfn "%s" errorMsg + + let strictMsg = + $"Evaluation failed\n file=%A{file}\n asExpression=%b{asExpression}, text=%s{text}\n stdout=%s{e.Result.Output.Merged}\n stderr=%s{e.Result.Error.Merged}\n inner exception=%A{e.InnerException}" + + onError strictMsg { Output = None FsiOutput = None