From ce5347471418336736010ca69d548f669b948d29 Mon Sep 17 00:00:00 2001 From: Thorsten Sommer Date: Mon, 19 Jan 2026 16:07:35 +0100 Subject: [PATCH] Improved Pandoc error handling and logging --- app/MindWork AI Studio/Tools/Pandoc.cs | 8 ++- .../Tools/PandocProcessBuilder.cs | 64 +++++++++++++++---- .../wwwroot/changelog/v26.1.2.md | 3 +- 3 files changed, 58 insertions(+), 17 deletions(-) diff --git a/app/MindWork AI Studio/Tools/Pandoc.cs b/app/MindWork AI Studio/Tools/Pandoc.cs index afce67f9..dba5be66 100644 --- a/app/MindWork AI Studio/Tools/Pandoc.cs +++ b/app/MindWork AI Studio/Tools/Pandoc.cs @@ -44,13 +44,15 @@ public static partial class Pandoc try { var preparedProcess = await PreparePandocProcess().AddArgument("--version").BuildAsync(rustService); + LOG.LogDebug("Checking Pandoc availability using executable: '{Executable}' (IsLocal: {IsLocal}).", preparedProcess.StartInfo.FileName, preparedProcess.IsLocal); + using var process = Process.Start(preparedProcess.StartInfo); if (process == null) { if (showMessages) await MessageBus.INSTANCE.SendError(new (Icons.Material.Filled.Help, TB("Was not able to check the Pandoc installation."))); - LOG.LogInformation("The Pandoc process was not started, it was null"); + LOG.LogInformation("The Pandoc process was not started, it was null. Executable path: '{Executable}'.", preparedProcess.StartInfo.FileName); return new(false, TB("Was not able to check the Pandoc installation."), false, string.Empty, preparedProcess.IsLocal); } @@ -105,8 +107,8 @@ public static partial class Pandoc { if (showMessages) await MessageBus.INSTANCE.SendError(new (@Icons.Material.Filled.AppsOutage, TB("It seems that Pandoc is not installed."))); - - LOG.LogError("Pandoc is not installed and threw an exception: {0}", e.Message); + + LOG.LogError(e, "Pandoc availability check failed. This usually means Pandoc is not installed or not in the system PATH."); return new(false, TB("It seems that Pandoc is not installed."), false, string.Empty, false); } } diff --git a/app/MindWork AI Studio/Tools/PandocProcessBuilder.cs b/app/MindWork AI Studio/Tools/PandocProcessBuilder.cs index 90bfb468..0b856486 100644 --- a/app/MindWork AI Studio/Tools/PandocProcessBuilder.cs +++ b/app/MindWork AI Studio/Tools/PandocProcessBuilder.cs @@ -14,7 +14,8 @@ public sealed class PandocProcessBuilder private static readonly Assembly ASSEMBLY = Assembly.GetExecutingAssembly(); private static readonly MetaDataArchitectureAttribute META_DATA_ARCH = ASSEMBLY.GetCustomAttribute()!; private static readonly RID CPU_ARCHITECTURE = META_DATA_ARCH.Architecture.ToRID(); - + private static readonly ILogger LOGGER = Program.LOGGER_FACTORY.CreateLogger(nameof(PandocProcessBuilder)); + private string? providedInputFile; private string? providedOutputFile; private string? providedInputFormat; @@ -116,25 +117,62 @@ public sealed class PandocProcessBuilder // Any local installation should be preferred over the system-wide installation. // var localInstallationRootDirectory = await Pandoc.GetPandocDataFolder(rustService); - try + + // + // Check if the data directory path is valid: + // + if (string.IsNullOrWhiteSpace(localInstallationRootDirectory)) + LOGGER.LogWarning("The local data directory path is empty or null. Cannot search for local Pandoc installation."); + + else if (!Directory.Exists(localInstallationRootDirectory)) + LOGGER.LogWarning("The local Pandoc installation directory does not exist: '{LocalInstallationRootDirectory}'.", localInstallationRootDirectory); + + else { + // + // The directory exists, search for the pandoc executable: + // var executableName = PandocExecutableName; - var subdirectories = Directory.GetDirectories(localInstallationRootDirectory, "*", SearchOption.AllDirectories); - foreach (var subdirectory in subdirectories) + LOGGER.LogDebug("Searching for Pandoc executable '{ExecutableName}' in: '{LocalInstallationRootDirectory}'.", executableName, localInstallationRootDirectory); + + try { - var pandocPath = Path.Combine(subdirectory, executableName); - if (File.Exists(pandocPath)) - return new(pandocPath, true); + // + // First, check the root directory itself: + // + var rootExecutablePath = Path.Combine(localInstallationRootDirectory, executableName); + if (File.Exists(rootExecutablePath)) + { + LOGGER.LogInformation("Found local Pandoc installation at the root path: '{Path}'.", rootExecutablePath); + return new(rootExecutablePath, true); + } + + // + // Then, search all subdirectories: + // + var subdirectories = Directory.GetDirectories(localInstallationRootDirectory, "*", SearchOption.AllDirectories); + foreach (var subdirectory in subdirectories) + { + var pandocPath = Path.Combine(subdirectory, executableName); + if (File.Exists(pandocPath)) + { + LOGGER.LogInformation("Found local Pandoc installation at: '{Path}'.", pandocPath); + return new(pandocPath, true); + } + } + + LOGGER.LogWarning("No Pandoc executable found in local installation directory or its subdirectories."); + } + catch (Exception ex) + { + LOGGER.LogWarning(ex, "Error while searching for a local Pandoc installation in: '{LocalInstallationRootDirectory}'.", localInstallationRootDirectory); } } - catch - { - // ignored - } - + // - // When no local installation was found, we assume that the pandoc executable is in the system PATH. + // When no local installation was found, we assume that the pandoc executable is in the system PATH: // + LOGGER.LogWarning("Falling back to system PATH for the Pandoc executable: '{ExecutableName}'.", PandocExecutableName); return new(PandocExecutableName, false); } diff --git a/app/MindWork AI Studio/wwwroot/changelog/v26.1.2.md b/app/MindWork AI Studio/wwwroot/changelog/v26.1.2.md index b3d253b6..dda49a92 100644 --- a/app/MindWork AI Studio/wwwroot/changelog/v26.1.2.md +++ b/app/MindWork AI Studio/wwwroot/changelog/v26.1.2.md @@ -1,7 +1,8 @@ # v26.1.2, build 232 (2026-01-xx xx:xx UTC) - Added the option to hide specific assistants by configuration plugins. This is useful for enterprise environments in organizations. - Added the current date and time to the system prompt for better context in conversations. Thanks Peer `peerschuett` for the contribution. -- Improved error handling for model loading in provider dialogs (LLMs, embeddings, transcriptions). +- Improved the error handling for the model loading in provider dialogs (LLMs, embeddings, transcriptions). +- Improved the error handling when checking the Pandoc installation. - Improved the microphone handling (transcription preview) so that all sound effects and the voice recording are processed without interruption. - Improved the handling of self-hosted providers in the configuration dialogs (LLMs, embeddings, and transcriptions) when the host cannot provide a list of models. - Improved the document analysis assistant (in preview) by allowing users to send results to a new chat to ask follow-up questions. Thanks to Sabrina `Sabrina-devops` for this contribution.