feat: add logging enhancements by integrating pino and pino-pretty for improved error tracking and debugging across the application

This commit is contained in:
Julien Froidefond
2025-10-26 06:15:47 +01:00
parent 7cc72dc13d
commit 52350a43d9
84 changed files with 455 additions and 177 deletions

View File

@@ -12,6 +12,7 @@ import Image from "next/image";
import Link from "next/link";
import { BookOfflineButton } from "@/components/ui/book-offline-button";
import { useTranslate } from "@/hooks/useTranslate";
import logger from "@/lib/logger";
type BookStatus = "idle" | "downloading" | "available" | "error";
@@ -54,7 +55,7 @@ export function DownloadManager() {
status,
});
} catch (error) {
console.error(`Erreur lors de la récupération du livre ${bookId}:`, error);
logger.error({ err: error }, `Erreur lors de la récupération du livre ${bookId}:`);
localStorage.removeItem(key);
}
}
@@ -62,7 +63,7 @@ export function DownloadManager() {
}
setDownloadedBooks(books);
} catch (error) {
console.error("Erreur lors du chargement des livres:", error);
logger.error({ err: error }, "Erreur lors du chargement des livres:");
toast({
title: "Erreur",
description: "Impossible de charger les livres téléchargés",
@@ -122,7 +123,7 @@ export function DownloadManager() {
description: t("downloads.toast.deletedDesc"),
});
} catch (error) {
console.error("Erreur lors de la suppression du livre:", error);
logger.error({ err: error }, "Erreur lors de la suppression du livre:");
toast({
title: t("downloads.toast.error"),
description: t("downloads.toast.errorDesc"),

View File

@@ -9,6 +9,7 @@ import { PullToRefreshIndicator } from "@/components/common/PullToRefreshIndicat
import { usePullToRefresh } from "@/hooks/usePullToRefresh";
import { ERROR_CODES } from "@/constants/errorCodes";
import type { HomeData } from "@/types/home";
import logger from "@/lib/logger";
export function ClientHomePage() {
const router = useRouter();
@@ -41,7 +42,7 @@ export function ClientHomePage() {
const homeData = await response.json();
setData(homeData);
} catch (err) {
console.error("Error fetching home data:", err);
logger.error({ err }, "Error fetching home data");
setError(err instanceof Error ? err.message : ERROR_CODES.KOMGA.SERVER_UNREACHABLE);
} finally {
setLoading(false);
@@ -78,7 +79,7 @@ export function ClientHomePage() {
return { success: true };
} catch (error) {
console.error("Erreur lors du rafraîchissement:", error);
logger.error({ err: error }, "Erreur lors du rafraîchissement:");
return { success: false, error: "Erreur lors du rafraîchissement de la page d'accueil" };
}
};

View File

@@ -18,7 +18,7 @@ interface HeroSectionProps {
export function HeroSection({ series }: HeroSectionProps) {
const { t } = useTranslate();
// console.log("HeroSection - Séries reçues:", {
// logger.info("HeroSection - Séries reçues:", {
// count: series?.length || 0,
// firstSeries: series?.[0],
// });

View File

@@ -28,7 +28,7 @@ export function HomeContent({ data, refreshHome }: HomeContentProps) {
}, [data.ongoing]);
// Vérification des données pour le debug
// console.log("HomeContent - Données reçues:", {
// logger.info("HomeContent - Données reçues:", {
// ongoingCount: data.ongoing?.length || 0,
// recentlyReadCount: data.recentlyRead?.length || 0,
// onDeckCount: data.onDeck?.length || 0,

View File

@@ -12,6 +12,7 @@ import { NetworkStatus } from "../ui/NetworkStatus";
import { usePreferences } from "@/contexts/PreferencesContext";
import { ImageCacheProvider } from "@/contexts/ImageCacheContext";
import type { KomgaLibrary, KomgaSeries } from "@/types/komga";
import logger from "@/lib/logger";
// Routes qui ne nécessitent pas d'authentification
const publicRoutes = ["/login", "/register"];
@@ -52,7 +53,7 @@ export default function ClientLayout({ children, initialLibraries = [], initialF
setRandomBookId(data.bookId);
}
} catch (error) {
console.error("Erreur lors de la récupération d'un book aléatoire:", error);
logger.error({ err: error }, "Erreur lors de la récupération d'un book aléatoire:");
}
}
}, [backgroundType, libraryIdsString]);

View File

@@ -14,6 +14,7 @@ import { useToast } from "@/components/ui/use-toast";
import { useTranslate } from "@/hooks/useTranslate";
import { NavButton } from "@/components/ui/nav-button";
import { IconButton } from "@/components/ui/icon-button";
import logger from "@/lib/logger";
interface SidebarProps {
isOpen: boolean;
@@ -44,7 +45,7 @@ export function Sidebar({ isOpen, onClose, initialLibraries, initialFavorites, u
const data = await response.json();
setLibraries(data);
} catch (error) {
console.error("Erreur de chargement des bibliothèques:", error);
logger.error({ err: error }, "Erreur de chargement des bibliothèques:");
toast({
title: "Erreur",
description:
@@ -82,7 +83,7 @@ export function Sidebar({ isOpen, onClose, initialLibraries, initialFavorites, u
const results = await Promise.all(promises);
setFavorites(results.filter((series): series is KomgaSeries => series !== null));
} catch (error) {
console.error("Erreur de chargement des favoris:", error);
logger.error({ err: error }, "Erreur de chargement des favoris:");
toast({
title: "Erreur",
description:
@@ -126,7 +127,7 @@ export function Sidebar({ isOpen, onClose, initialLibraries, initialFavorites, u
setFavorites([]);
onClose();
} catch (error) {
console.error("Erreur lors de la déconnexion:", error);
logger.error({ err: error }, "Erreur lors de la déconnexion:");
toast({
title: "Erreur",
description: "Une erreur est survenue lors de la déconnexion",

View File

@@ -7,6 +7,7 @@ import { useToast } from "@/components/ui/use-toast";
import { cn } from "@/lib/utils";
import { useTranslation } from "react-i18next";
import { useRouter } from "next/navigation";
import logger from "@/lib/logger";
interface ScanButtonProps {
libraryId: string;
@@ -51,7 +52,7 @@ export function ScanButton({ libraryId }: ScanButtonProps) {
description: t("library.scan.complete.description"),
});
} catch (error) {
console.error("Error invalidating cache after scan:", error);
logger.error({ err: error }, "Error invalidating cache after scan:");
toast({
variant: "destructive",
title: t("library.scan.error.title"),

View File

@@ -6,6 +6,7 @@ import { BookSkeleton } from "@/components/skeletons/BookSkeleton";
import { ErrorMessage } from "@/components/ui/ErrorMessage";
import { ERROR_CODES } from "@/constants/errorCodes";
import type { KomgaBook } from "@/types/komga";
import logger from "@/lib/logger";
interface ClientBookPageProps {
bookId: string;
@@ -35,7 +36,7 @@ export function ClientBookPage({ bookId }: ClientBookPageProps) {
const bookData = await response.json();
setData(bookData);
} catch (err) {
console.error("Error fetching book:", err);
logger.error({ err }, "Error fetching book");
setError(err instanceof Error ? err.message : ERROR_CODES.BOOK.PAGES_FETCH_ERROR);
} finally {
setLoading(false);

View File

@@ -2,6 +2,7 @@ import type { ThumbnailProps } from "../types";
import { ImageLoader } from "@/components/ui/image-loader";
import { cn } from "@/lib/utils";
import { forwardRef, useEffect, useState, useCallback, useRef, useImperativeHandle } from "react";
import logger from "@/lib/logger";
export const Thumbnail = forwardRef<HTMLButtonElement, ThumbnailProps>(
(
@@ -73,7 +74,7 @@ export const Thumbnail = forwardRef<HTMLButtonElement, ThumbnailProps>(
setIsLoading(false);
}
} catch (error) {
console.error(`Erreur lors du chargement de la miniature ${pageNumber}:`, error);
logger.error({ err: error }, `Erreur lors du chargement de la miniature ${pageNumber}:`);
setHasError(true);
setIsLoading(false);
}
@@ -103,7 +104,7 @@ export const Thumbnail = forwardRef<HTMLButtonElement, ThumbnailProps>(
});
}, delay);
} else {
console.error(
logger.error(
`Échec du chargement de l'image pour la page ${pageNumber} après ${maxAttempts} tentatives`
);
setHasError(true);

View File

@@ -1,4 +1,5 @@
import { useState, useEffect } from "react";
import logger from "@/lib/logger";
export const useFullscreen = () => {
const [isFullscreen, setIsFullscreen] = useState(false);
@@ -13,7 +14,7 @@ export const useFullscreen = () => {
return () => {
document.removeEventListener("fullscreenchange", handleFullscreenChange);
if (document.fullscreenElement) {
document.exitFullscreen().catch(console.error);
document.exitFullscreen().catch(err => logger.error({ err }, "Erreur lors de la sortie du mode plein écran"));
}
};
}, []);
@@ -26,7 +27,7 @@ export const useFullscreen = () => {
await element.requestFullscreen();
}
} catch (error) {
console.error("Erreur lors du changement de mode plein écran:", error);
logger.error({ err: error }, "Erreur lors du changement de mode plein écran:");
}
};

View File

@@ -1,4 +1,5 @@
import { useState, useCallback, useEffect, useRef } from "react";
import logger from "@/lib/logger";
interface ImageDimensions {
width: number;
@@ -200,7 +201,7 @@ export function useImageLoader({ bookId, pages: _pages, prefetchCount = 5, nextB
setImageBlobUrls(newUrls);
} catch (error) {
console.error('Error reloading images:', error);
logger.error({ err: error }, 'Error reloading images:');
throw error;
}
}, [imageBlobUrls, getPageUrl]);

View File

@@ -2,6 +2,7 @@ import { useState, useCallback, useRef, useEffect } from "react";
import { useRouter } from "next/navigation";
import { ClientOfflineBookService } from "@/lib/services/client-offlinebook.service";
import type { KomgaBook } from "@/types/komga";
import logger from "@/lib/logger";
interface UsePageNavigationProps {
book: KomgaBook;
@@ -46,7 +47,7 @@ export function usePageNavigation({
body: JSON.stringify({ page, completed }),
});
} catch (error) {
console.error("Sync error:", error);
logger.error({ err: error }, "Sync error:");
}
},
[book, pages.length]

View File

@@ -12,6 +12,7 @@ import { useTranslate } from "@/hooks/useTranslate";
import { SeriesCover } from "@/components/ui/series-cover";
import { StatusBadge } from "@/components/ui/status-badge";
import { IconButton } from "@/components/ui/icon-button";
import logger from "@/lib/logger";
interface SeriesHeaderProps {
series: KomgaSeries;
@@ -33,7 +34,7 @@ export const SeriesHeader = ({ series, refreshSeries }: SeriesHeaderProps) => {
const favoriteIds = await response.json();
setIsFavorite(favoriteIds.includes(series.id));
} catch (error) {
console.error("Erreur lors de la vérification des favoris:", error);
logger.error({ err: error }, "Erreur lors de la vérification des favoris:");
toast({
title: "Erreur",
description:
@@ -75,7 +76,7 @@ export const SeriesHeader = ({ series, refreshSeries }: SeriesHeaderProps) => {
);
}
} catch (error) {
console.error("Erreur lors de la modification des favoris:", error);
logger.error({ err: error }, "Erreur lors de la modification des favoris:");
toast({
title: "Erreur",
description:

View File

@@ -6,6 +6,7 @@ import { useToast } from "@/components/ui/use-toast";
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card";
import { Activity, ImageIcon, Shield, Info } from "lucide-react";
import { Badge } from "@/components/ui/badge";
import logger from "@/lib/logger";
export function AdvancedSettings() {
const { t } = useTranslate();
@@ -22,7 +23,7 @@ export function AdvancedSettings() {
description: t("settings.komga.messages.configSaved"),
});
} catch (error) {
console.error("Erreur:", error);
logger.error({ err: error }, "Erreur:");
toast({
variant: "destructive",
title: t("settings.error.title"),
@@ -41,7 +42,7 @@ export function AdvancedSettings() {
description: t("settings.komga.messages.configSaved"),
});
} catch (error) {
console.error("Erreur:", error);
logger.error({ err: error }, "Erreur:");
toast({
variant: "destructive",
title: t("settings.error.title"),
@@ -63,7 +64,7 @@ export function AdvancedSettings() {
description: t("settings.komga.messages.configSaved"),
});
} catch (error) {
console.error("Erreur:", error);
logger.error({ err: error }, "Erreur:");
toast({
variant: "destructive",
title: t("settings.error.title"),

View File

@@ -15,6 +15,7 @@ import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/com
import { Slider } from "@/components/ui/slider";
import { Checkbox } from "@/components/ui/checkbox";
import type { KomgaLibrary } from "@/types/komga";
import logger from "@/lib/logger";
export function BackgroundSettings() {
const { t } = useTranslate();
@@ -38,7 +39,7 @@ export function BackgroundSettings() {
setKomgaConfigValid(libs.length > 0);
}
} catch (error) {
console.error("Erreur lors de la vérification de la config Komga:", error);
logger.error({ err: error }, "Erreur lors de la vérification de la config Komga:");
setKomgaConfigValid(false);
}
};
@@ -58,7 +59,7 @@ export function BackgroundSettings() {
description: t("settings.komga.messages.configSaved"),
});
} catch (error) {
console.error("Erreur:", error);
logger.error({ err: error }, "Erreur:");
toast({
variant: "destructive",
title: t("settings.error.title"),
@@ -80,7 +81,7 @@ export function BackgroundSettings() {
description: t("settings.komga.messages.configSaved"),
});
} catch (error) {
console.error("Erreur:", error);
logger.error({ err: error }, "Erreur:");
toast({
variant: "destructive",
title: t("settings.error.title"),
@@ -111,7 +112,7 @@ export function BackgroundSettings() {
description: t("settings.komga.messages.configSaved"),
});
} catch (error) {
console.error("Erreur:", error);
logger.error({ err: error }, "Erreur:");
toast({
variant: "destructive",
title: t("settings.error.title"),
@@ -129,7 +130,7 @@ export function BackgroundSettings() {
},
});
} catch (error) {
console.error("Erreur:", error);
logger.error({ err: error }, "Erreur:");
}
};
@@ -142,7 +143,7 @@ export function BackgroundSettings() {
},
});
} catch (error) {
console.error("Erreur:", error);
logger.error({ err: error }, "Erreur:");
}
};
@@ -152,7 +153,7 @@ export function BackgroundSettings() {
const newOpacity = Math.max(0, Math.min(100, currentOpacity + delta));
await handleOpacityChange([newOpacity]);
} catch (error) {
console.error("Erreur ajustement opacité:", error);
logger.error({ err: error }, "Erreur ajustement opacité:");
}
};
@@ -162,7 +163,7 @@ export function BackgroundSettings() {
const newBlur = Math.max(0, Math.min(20, currentBlur + delta));
await handleBlurChange([newBlur]);
} catch (error) {
console.error("Erreur ajustement flou:", error);
logger.error({ err: error }, "Erreur ajustement flou:");
}
};
@@ -181,7 +182,7 @@ export function BackgroundSettings() {
},
});
} catch (error) {
console.error("Erreur:", error);
logger.error({ err: error }, "Erreur:");
}
};

View File

@@ -5,6 +5,7 @@ import { Label } from "@/components/ui/label";
import { Switch } from "@/components/ui/switch";
import { useToast } from "@/components/ui/use-toast";
import { usePreferences } from "@/contexts/PreferencesContext";
import logger from "@/lib/logger";
export function CacheModeSwitch() {
const [isLoading, setIsLoading] = useState(false);
@@ -33,7 +34,7 @@ export function CacheModeSwitch() {
description: `Le cache est maintenant en mode ${checked ? "mémoire" : "fichier"}`,
});
} catch (error) {
console.error("Erreur lors de la modification du mode de cache:", error);
logger.error({ err: error }, "Erreur lors de la modification du mode de cache:");
toast({
variant: "destructive",
title: "Erreur",

View File

@@ -10,6 +10,7 @@ import type { TTLConfigData } from "@/types/komga";
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { useImageCache } from "@/contexts/ImageCacheContext";
import logger from "@/lib/logger";
interface CacheSettingsProps {
initialTTLConfig: TTLConfigData | null;
@@ -141,7 +142,7 @@ export function CacheSettings({ initialTTLConfig }: CacheSettingsProps) {
setApiCacheSize(apiSize);
}
} catch (error) {
console.error("Erreur lors de la récupération de la taille du cache:", error);
logger.error({ err: error }, "Erreur lors de la récupération de la taille du cache:");
} finally {
setIsLoadingCacheSize(false);
}
@@ -156,7 +157,7 @@ export function CacheSettings({ initialTTLConfig }: CacheSettingsProps) {
setCacheEntries(data.entries);
}
} catch (error) {
console.error("Erreur lors de la récupération des entrées du cache:", error);
logger.error({ err: error }, "Erreur lors de la récupération des entrées du cache:");
} finally {
setIsLoadingEntries(false);
}
@@ -196,7 +197,7 @@ export function CacheSettings({ initialTTLConfig }: CacheSettingsProps) {
setSwCacheEntries(entries);
}
} catch (error) {
console.error("Erreur lors de la récupération des entrées du cache SW:", error);
logger.error({ err: error }, "Erreur lors de la récupération des entrées du cache SW:");
} finally {
setIsLoadingSwEntries(false);
}
@@ -345,7 +346,7 @@ export function CacheSettings({ initialTTLConfig }: CacheSettingsProps) {
await fetchSwCacheEntries();
}
} catch (error) {
console.error("Erreur:", error);
logger.error({ err: error }, "Erreur:");
toast({
variant: "destructive",
title: t("settings.cache.error.title"),
@@ -389,7 +390,7 @@ export function CacheSettings({ initialTTLConfig }: CacheSettingsProps) {
}, 1000);
}
} catch (error) {
console.error("Erreur lors de la suppression des caches:", error);
logger.error({ err: error }, "Erreur lors de la suppression des caches:");
toast({
variant: "destructive",
title: t("settings.cache.error.title"),
@@ -438,7 +439,7 @@ export function CacheSettings({ initialTTLConfig }: CacheSettingsProps) {
description: t("settings.cache.messages.ttlSaved"),
});
} catch (error) {
console.error("Erreur lors de la sauvegarde:", error);
logger.error({ err: error }, "Erreur lors de la sauvegarde:");
toast({
variant: "destructive",
title: t("settings.cache.error.title"),

View File

@@ -4,6 +4,7 @@ import { Switch } from "@/components/ui/switch";
import { Label } from "@/components/ui/label";
import { useToast } from "@/components/ui/use-toast";
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card";
import logger from "@/lib/logger";
export function DisplaySettings() {
const { t } = useTranslate();
@@ -18,7 +19,7 @@ export function DisplaySettings() {
description: t("settings.komga.messages.configSaved"),
});
} catch (error) {
console.error("Erreur détaillée:", error);
logger.error({ err: error }, "Erreur détaillée:");
toast({
variant: "destructive",
title: t("settings.error.title"),
@@ -65,7 +66,7 @@ export function DisplaySettings() {
description: t("settings.komga.messages.configSaved"),
});
} catch (error) {
console.error("Erreur détaillée:", error);
logger.error({ err: error }, "Erreur détaillée:");
toast({
variant: "destructive",
title: t("settings.error.title"),

View File

@@ -6,6 +6,7 @@ import { useToast } from "@/components/ui/use-toast";
import { Network, Loader2 } from "lucide-react";
import type { KomgaConfig } from "@/types/komga";
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card";
import logger from "@/lib/logger";
interface KomgaSettingsProps {
initialConfig: KomgaConfig | null;
@@ -61,7 +62,7 @@ export function KomgaSettings({ initialConfig }: KomgaSettingsProps) {
description: t("settings.komga.messages.connectionSuccess"),
});
} catch (error) {
console.error("Erreur:", error);
logger.error({ err: error }, "Erreur:");
toast({
variant: "destructive",
title: t("settings.komga.error.title"),
@@ -125,7 +126,7 @@ export function KomgaSettings({ initialConfig }: KomgaSettingsProps) {
// Forcer un rechargement complet de la page
window.location.reload();
} catch (error) {
console.error("Erreur lors de la sauvegarde:", error);
logger.error({ err: error }, "Erreur lors de la sauvegarde:");
toast({
variant: "destructive",
title: t("settings.komga.error.title"),

View File

@@ -3,6 +3,7 @@
import { AlertCircle, RefreshCw } from "lucide-react";
import { useTranslate } from "@/hooks/useTranslate";
import { Button } from "@/components/ui/button";
import logger from "@/lib/logger";
interface ErrorMessageProps {
errorCode: string;
@@ -23,7 +24,7 @@ export const ErrorMessage = ({
const message = t(`errors.${errorCode}`);
if (error) {
console.error(error);
logger.error(error);
}
if (variant === "form") {

View File

@@ -2,6 +2,7 @@
import { useEffect, useState } from "react";
import { Download, X } from "lucide-react";
import logger from "@/lib/logger";
interface BeforeInstallPromptEvent extends Event {
prompt: () => Promise<void>;
@@ -83,7 +84,7 @@ export function InstallPWA() {
setIsInstallable(false);
}
} catch (error) {
console.error("Erreur lors de l'installation:", error);
logger.error({ err: error }, "Erreur lors de l'installation:");
}
setDeferredPrompt(null);

View File

@@ -5,6 +5,7 @@ import { Download, Check, Loader2 } from "lucide-react";
import { Button } from "./button";
import { useToast } from "./use-toast";
import type { KomgaBook } from "@/types/komga";
import logger from "@/lib/logger";
interface BookOfflineButtonProps {
book: KomgaBook;
@@ -81,7 +82,7 @@ export function BookOfflineButton({ book, className }: BookOfflineButtonProps) {
retryCount++;
if (retryCount === maxRetries) {
failedPages++;
console.error(
logger.error(
`Échec du téléchargement de la page ${i} après ${maxRetries} tentatives`
);
}
@@ -97,7 +98,7 @@ export function BookOfflineButton({ book, className }: BookOfflineButtonProps) {
retryCount++;
if (retryCount === maxRetries) {
failedPages++;
console.error(`Erreur lors du téléchargement de la page ${i}:`, error);
logger.error({ err: error }, `Erreur lors du téléchargement de la page ${i}:`);
}
await new Promise((resolve) => setTimeout(resolve, 1000));
}
@@ -143,7 +144,7 @@ export function BookOfflineButton({ book, className }: BookOfflineButtonProps) {
});
}
} catch (error) {
console.error("Erreur lors du téléchargement:", error);
logger.error({ err: error }, "Erreur lors du téléchargement:");
// Ne pas changer le statut si le téléchargement a été volontairement annulé
if ((error as Error)?.message !== "Téléchargement annulé") {
setBookStatus(book.id, { status: "error", progress: 0, timestamp: Date.now() });
@@ -191,7 +192,7 @@ export function BookOfflineButton({ book, className }: BookOfflineButtonProps) {
timestamp: Date.now(),
});
} catch (error) {
console.error("Erreur lors de la vérification du cache:", error);
logger.error({ err: error }, "Erreur lors de la vérification du cache:");
setBookStatus(book.id, { status: "error", progress: 0, timestamp: Date.now() });
}
}, [book.id, book.media.pagesCount, setBookStatus]);
@@ -255,7 +256,7 @@ export function BookOfflineButton({ book, className }: BookOfflineButtonProps) {
await downloadBook();
}
} catch (error) {
console.error("Erreur lors de la gestion du cache:", error);
logger.error({ err: error }, "Erreur lors de la gestion du cache:");
setBookStatus(book.id, { status: "error", progress: 0, timestamp: Date.now() });
toast({
title: "Erreur",

View File

@@ -6,6 +6,7 @@ import { useToast } from "./use-toast";
import { ClientOfflineBookService } from "@/lib/services/client-offlinebook.service";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import logger from "@/lib/logger";
interface MarkAsReadButtonProps {
bookId: string;
@@ -49,7 +50,7 @@ export function MarkAsReadButton({
});
onSuccess?.();
} catch (error) {
console.error("Erreur lors de la mise à jour du progresseur de lecture:", error);
logger.error({ err: error }, "Erreur lors de la mise à jour du progresseur de lecture:");
toast({
title: t("books.actions.markAsRead.error.title"),
description: t("books.actions.markAsRead.error.description"),

View File

@@ -6,6 +6,7 @@ import { useToast } from "./use-toast";
import { ClientOfflineBookService } from "@/lib/services/client-offlinebook.service";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import logger from "@/lib/logger";
interface MarkAsUnreadButtonProps {
bookId: string;
@@ -39,7 +40,7 @@ export function MarkAsUnreadButton({ bookId, onSuccess, className }: MarkAsUnrea
});
onSuccess?.();
} catch (error) {
console.error("Erreur lors de la mise à jour du progresseur de lecture:", error);
logger.error({ err: error }, "Erreur lors de la mise à jour du progresseur de lecture:");
toast({
title: t("books.actions.markAsUnread.error.title"),
description: t("books.actions.markAsUnread.error.description"),