Enhanced logging & error handling for auth and pg backups

- Add detailed debug/warning logs to authentication flows (AuthService, AuthorizationContext, WebSocketManager) for better traceability of auth attempts and failures.
- Log WebSocket authentication attempts, including IP, path, and token preview.
- Introduce PostgresVersionMismatchException for pg_dump/pg_restore version mismatches; parse and log server/client versions, clean up failed backups, and provide upgrade guidance.
- Add helper for parsing version mismatch errors.
- Update using directives and minor code cleanups.
- Update .csproj.user with new publish profile path.
This commit is contained in:
2026-03-04 12:37:39 -05:00
parent 895372fe98
commit 667c3768a9
8 changed files with 197 additions and 3 deletions
@@ -0,0 +1,55 @@
// <copyright file="PostgresVersionMismatchException.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>
namespace Jellyfin.Database.Providers.Postgres.Exceptions;
using System;
/// <summary>
/// Exception thrown when there is a version mismatch between PostgreSQL server and client tools (pg_dump/pg_restore).
/// </summary>
public class PostgresVersionMismatchException : Exception
{
/// <summary>
/// Initializes a new instance of the <see cref="PostgresVersionMismatchException"/> class.
/// </summary>
/// <param name="serverVersion">The PostgreSQL server version.</param>
/// <param name="clientVersion">The pg_dump/pg_restore client version.</param>
public PostgresVersionMismatchException(string serverVersion, string clientVersion)
: base(BuildMessage(serverVersion, clientVersion))
{
ServerVersion = serverVersion;
ClientVersion = clientVersion;
}
/// <summary>
/// Initializes a new instance of the <see cref="PostgresVersionMismatchException"/> class.
/// </summary>
/// <param name="serverVersion">The PostgreSQL server version.</param>
/// <param name="clientVersion">The pg_dump/pg_restore client version.</param>
/// <param name="innerException">The inner exception.</param>
public PostgresVersionMismatchException(string serverVersion, string clientVersion, Exception innerException)
: base(BuildMessage(serverVersion, clientVersion), innerException)
{
ServerVersion = serverVersion;
ClientVersion = clientVersion;
}
/// <summary>
/// Gets the PostgreSQL server version.
/// </summary>
public string ServerVersion { get; }
/// <summary>
/// Gets the pg_dump/pg_restore client version.
/// </summary>
public string ClientVersion { get; }
private static string BuildMessage(string serverVersion, string clientVersion)
{
return $"PostgreSQL server version ({serverVersion}) does not match pg_dump version ({clientVersion}). " +
"Please upgrade your PostgreSQL client tools to match or exceed the server version. " +
"You can specify a custom path to pg_dump in the database backup options configuration.";
}
}
@@ -10,9 +10,11 @@ using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using Jellyfin.Database.Implementations.DbConfiguration;
using Jellyfin.Database.Providers.Postgres.Exceptions;
using MediaBrowser.Common.Configuration;
using Microsoft.Extensions.Logging;
@@ -137,6 +139,26 @@ public class PostgresBackupService
var errorMessage = errorBuilder.ToString();
_logger.LogError("pg_dump failed with exit code {ExitCode}: {Error}", process.ExitCode, errorMessage);
// Check for version mismatch error
if (errorMessage.Contains("server version mismatch", StringComparison.OrdinalIgnoreCase))
{
var (serverVersion, clientVersion) = ParseVersionMismatchError(errorMessage);
_logger.LogError(
"PostgreSQL version mismatch detected - Server: {ServerVersion}, pg_dump: {ClientVersion}. " +
"Please upgrade your PostgreSQL client tools to match the server version.",
serverVersion,
clientVersion);
// Clean up failed backup file
if (File.Exists(fullBackupPath))
{
File.Delete(fullBackupPath);
}
throw new PostgresVersionMismatchException(serverVersion, clientVersion);
}
// Clean up failed backup file
if (File.Exists(fullBackupPath))
{
@@ -478,4 +500,31 @@ public class PostgresBackupService
_ => "dump"
};
}
/// <summary>
/// Parses PostgreSQL version mismatch error message to extract server and client versions.
/// </summary>
/// <param name="errorMessage">The error message from pg_dump.</param>
/// <returns>A tuple containing server version and client version.</returns>
private static (string ServerVersion, string ClientVersion) ParseVersionMismatchError(string errorMessage)
{
var serverVersion = "unknown";
var clientVersion = "unknown";
// Parse server version: "server version: 18.3 (Debian 18.3-1.pgdg13+1)"
var serverMatch = Regex.Match(errorMessage, @"server version:\s*([^\s;]+(?:\s*\([^)]+\))?)", RegexOptions.IgnoreCase);
if (serverMatch.Success)
{
serverVersion = serverMatch.Groups[1].Value.Trim();
}
// Parse pg_dump version: "pg_dump version: 16.12 (Ubuntu 16.12-1.pgdg24.04+1)"
var clientMatch = Regex.Match(errorMessage, @"pg_dump version:\s*([^\s;]+(?:\s*\([^)]+\))?)", RegexOptions.IgnoreCase);
if (clientMatch.Success)
{
clientVersion = clientMatch.Groups[1].Value.Trim();
}
return (serverVersion, clientVersion);
}
}
@@ -18,6 +18,7 @@ using Jellyfin.Database.Implementations;
using Jellyfin.Database.Implementations.DbConfiguration;
using Jellyfin.Database.Implementations.Entities;
using Jellyfin.Database.Implementations.Entities.Security;
using Jellyfin.Database.Providers.Postgres.Exceptions;
using MediaBrowser.Common.Configuration;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
@@ -715,6 +716,17 @@ public sealed class PostgresDatabaseProvider : IJellyfinDatabaseProvider
logger.LogInformation("PostgreSQL local backup created: {BackupPath}", backupPath);
return Path.GetFileName(backupPath);
}
catch (PostgresVersionMismatchException versionEx)
{
logger.LogError(
versionEx,
"PostgreSQL version mismatch: Server version {ServerVersion} is incompatible with pg_dump version {ClientVersion}. " +
"Please upgrade your PostgreSQL client tools (pg_dump/pg_restore) to match or exceed the server version. " +
"You can install the latest PostgreSQL client tools from: https://www.postgresql.org/download/",
versionEx.ServerVersion,
versionEx.ClientVersion);
throw;
}
catch (Exception ex)
{
logger.LogError(ex, "Failed to create local PostgreSQL backup using pg_dump");