From d1ec27cb7b35499c24c612605f20e0841e1dce21 Mon Sep 17 00:00:00 2001 From: "alexei.dolgolyov" Date: Mon, 9 Feb 2026 12:03:25 +0300 Subject: [PATCH] Improve error handling for unavailable network shares - Add OSError/PermissionError handling in browse endpoint - Return 503 status code when folders are temporarily unavailable - Display user-friendly error messages in the UI - Enhance error logging with exception type information Co-Authored-By: Claude Sonnet 4.5 --- media_server/routes/browser.py | 9 ++++++++- media_server/static/js/app.js | 12 ++++++++++-- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/media_server/routes/browser.py b/media_server/routes/browser.py index 8760471..dee5e63 100644 --- a/media_server/routes/browser.py +++ b/media_server/routes/browser.py @@ -254,8 +254,15 @@ async def browse( raise HTTPException(status_code=400, detail=str(e)) except FileNotFoundError as e: raise HTTPException(status_code=404, detail=str(e)) + except (OSError, PermissionError) as e: + # Network share unavailable or access denied + logger.warning(f"Folder temporarily unavailable: {e}") + raise HTTPException( + status_code=503, + detail=f"Folder is temporarily unavailable. It may be a network share that is not accessible at the moment." + ) except Exception as e: - logger.error(f"Error browsing directory: {e}") + logger.error(f"Error browsing directory (type: {type(e).__name__}): {e}") raise HTTPException(status_code=500, detail="Failed to browse directory") diff --git a/media_server/static/js/app.js b/media_server/static/js/app.js index e0164cf..a905033 100644 --- a/media_server/static/js/app.js +++ b/media_server/static/js/app.js @@ -1579,7 +1579,14 @@ async function browsePath(folderId, path, offset = 0, nocache = false) { { headers: { 'Authorization': `Bearer ${token}` } } ); - if (!response.ok) throw new Error('Failed to browse path'); + if (!response.ok) { + let errorMsg = 'Failed to browse path'; + if (response.status === 503) { + const errorData = await response.json().catch(() => ({})); + errorMsg = errorData.detail || 'Folder is temporarily unavailable (network share not accessible)'; + } + throw new Error(errorMsg); + } const data = await response.json(); currentPath = data.current_path; @@ -1602,7 +1609,8 @@ async function browsePath(folderId, path, offset = 0, nocache = false) { saveLastBrowserPath(folderId, currentPath); } catch (error) { console.error('Error browsing path:', error); - showToast(t('browser.error_loading'), 'error'); + const errorMsg = error.message || t('browser.error_loading'); + showToast(errorMsg, 'error'); clearBrowserGrid(); } }