Improved Pandoc error handling and logging

This commit is contained in:
Thorsten Sommer 2026-01-19 16:07:35 +01:00
parent a1f69c8dad
commit ce53474714
Signed by untrusted user who does not match committer: tsommer
GPG Key ID: 371BBA77A02C0108
3 changed files with 58 additions and 17 deletions

View File

@ -44,13 +44,15 @@ public static partial class Pandoc
try try
{ {
var preparedProcess = await PreparePandocProcess().AddArgument("--version").BuildAsync(rustService); 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); using var process = Process.Start(preparedProcess.StartInfo);
if (process == null) if (process == null)
{ {
if (showMessages) if (showMessages)
await MessageBus.INSTANCE.SendError(new (Icons.Material.Filled.Help, TB("Was not able to check the Pandoc installation."))); 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); return new(false, TB("Was not able to check the Pandoc installation."), false, string.Empty, preparedProcess.IsLocal);
} }
@ -106,7 +108,7 @@ public static partial class Pandoc
if (showMessages) if (showMessages)
await MessageBus.INSTANCE.SendError(new (@Icons.Material.Filled.AppsOutage, TB("It seems that Pandoc is not installed."))); 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); return new(false, TB("It seems that Pandoc is not installed."), false, string.Empty, false);
} }
} }

View File

@ -14,6 +14,7 @@ public sealed class PandocProcessBuilder
private static readonly Assembly ASSEMBLY = Assembly.GetExecutingAssembly(); private static readonly Assembly ASSEMBLY = Assembly.GetExecutingAssembly();
private static readonly MetaDataArchitectureAttribute META_DATA_ARCH = ASSEMBLY.GetCustomAttribute<MetaDataArchitectureAttribute>()!; private static readonly MetaDataArchitectureAttribute META_DATA_ARCH = ASSEMBLY.GetCustomAttribute<MetaDataArchitectureAttribute>()!;
private static readonly RID CPU_ARCHITECTURE = META_DATA_ARCH.Architecture.ToRID(); 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? providedInputFile;
private string? providedOutputFile; private string? providedOutputFile;
@ -116,25 +117,62 @@ public sealed class PandocProcessBuilder
// Any local installation should be preferred over the system-wide installation. // Any local installation should be preferred over the system-wide installation.
// //
var localInstallationRootDirectory = await Pandoc.GetPandocDataFolder(rustService); var localInstallationRootDirectory = await Pandoc.GetPandocDataFolder(rustService);
//
// 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;
LOGGER.LogDebug("Searching for Pandoc executable '{ExecutableName}' in: '{LocalInstallationRootDirectory}'.", executableName, localInstallationRootDirectory);
try try
{ {
var executableName = PandocExecutableName; //
// 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); var subdirectories = Directory.GetDirectories(localInstallationRootDirectory, "*", SearchOption.AllDirectories);
foreach (var subdirectory in subdirectories) foreach (var subdirectory in subdirectories)
{ {
var pandocPath = Path.Combine(subdirectory, executableName); var pandocPath = Path.Combine(subdirectory, executableName);
if (File.Exists(pandocPath)) if (File.Exists(pandocPath))
{
LOGGER.LogInformation("Found local Pandoc installation at: '{Path}'.", pandocPath);
return new(pandocPath, true); return new(pandocPath, true);
} }
} }
catch
LOGGER.LogWarning("No Pandoc executable found in local installation directory or its subdirectories.");
}
catch (Exception ex)
{ {
// ignored LOGGER.LogWarning(ex, "Error while searching for a local Pandoc installation in: '{LocalInstallationRootDirectory}'.", localInstallationRootDirectory);
}
} }
// //
// 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); return new(PandocExecutableName, false);
} }

View File

@ -1,7 +1,8 @@
# v26.1.2, build 232 (2026-01-xx xx:xx UTC) # 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 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. - 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 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 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. - 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.