diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 36e9b92..2b62e7f 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -629,7 +629,34 @@ function App() { - + + + + Fetch Failed + + + Metadata fetch failed. Try using a high-quality VPN such as + Surfshark, ExpressVPN, Proton VPN, or a similar service. + + + Choose a location that is not blocked by Spotify or the + related service, such as the USA, UK, Germany, Netherlands, + or Singapore. + + + If you are already using a VPN, try switching to another + server and fetch again. + + + + + + + + + { }}> diff --git a/frontend/src/hooks/useMetadata.ts b/frontend/src/hooks/useMetadata.ts index 9e7a37e..18e57ef 100644 --- a/frontend/src/hooks/useMetadata.ts +++ b/frontend/src/hooks/useMetadata.ts @@ -8,6 +8,8 @@ import type { SpotifyMetadataResponse } from "@/types/api"; export function useMetadata() { const [loading, setLoading] = useState(false); const [metadata, setMetadata] = useState(null); + const [showVpnAdviceDialog, setShowVpnAdviceDialog] = useState(false); + const [fetchFailureReason, setFetchFailureReason] = useState(""); const loadingToastId = useRef(null); const fetchedCount = useRef(0); const currentName = useRef(""); @@ -18,6 +20,10 @@ export function useMetadata() { external_urls: string; } | null>(null); const [pendingArtistName, setPendingArtistName] = useState(null); + const showFetchFailureAdvice = (errorMsg: string) => { + setFetchFailureReason(errorMsg); + setShowVpnAdviceDialog(true); + }; const resolveArtistUrlBySearch = async (artistName: string): Promise => { const query = artistName.trim(); if (!query) { @@ -214,6 +220,7 @@ export function useMetadata() { const errorMsg = err instanceof Error ? err.message : "Failed to fetch metadata"; logger.error(`fetch failed: ${errorMsg}`); toast.error(errorMsg); + showFetchFailureAdvice(errorMsg); } finally { setLoading(false); @@ -316,6 +323,7 @@ export function useMetadata() { const errorMsg = err instanceof Error ? err.message : "Failed to fetch album metadata"; logger.error(`fetch failed: ${errorMsg}`); toast.error(errorMsg); + showFetchFailureAdvice(errorMsg); } finally { setLoading(false); @@ -325,6 +333,9 @@ export function useMetadata() { return { loading, metadata, + showVpnAdviceDialog, + setShowVpnAdviceDialog, + fetchFailureReason, showAlbumDialog, setShowAlbumDialog, selectedAlbum,