fix(frontend): URL-encode file paths in PDF viewer + add page error handling

- Encode filePath with encodeURIComponent to handle spaces/special chars
- Add page-level error handling in PdfViewerPage for better diagnostics
- Show PDF URL in error message to aid debugging
This commit is contained in:
Woody 2026-04-25 17:39:54 +08:00
parent 7a89651512
commit e34067fe9c
2 changed files with 13 additions and 2 deletions

View File

@ -41,7 +41,7 @@ export const deleteChunk = async (chunkId: string): Promise<DeleteResponse> => {
export const getChunkPdfUrl = (filePath: string): string => { export const getChunkPdfUrl = (filePath: string): string => {
const baseUrl: string = import.meta.env.VITE_API_BASE_URL ?? 'http://localhost:8000/api/v1' const baseUrl: string = import.meta.env.VITE_API_BASE_URL ?? 'http://localhost:8000/api/v1'
return `${baseUrl}/chunks/${filePath}/pdf` return `${baseUrl}/chunks/${encodeURIComponent(filePath)}/pdf`
} }
export const getPdfViewerUrl = (filePath: string, page?: number, title?: string): string => { export const getPdfViewerUrl = (filePath: string, page?: number, title?: string): string => {

View File

@ -20,16 +20,22 @@ export const PdfViewerPage: React.FC = () => {
const [pageNumber, setPageNumber] = useState<number>(initialPage) const [pageNumber, setPageNumber] = useState<number>(initialPage)
const [zoomIndex, setZoomIndex] = useState<number>(DEFAULT_ZOOM_INDEX) const [zoomIndex, setZoomIndex] = useState<number>(DEFAULT_ZOOM_INDEX)
const [loadError, setLoadError] = useState<string | null>(null) const [loadError, setLoadError] = useState<string | null>(null)
const [pageError, setPageError] = useState<string | null>(null)
const onDocumentLoadSuccess = useCallback(({ numPages: total }: { numPages: number }) => { const onDocumentLoadSuccess = useCallback(({ numPages: total }: { numPages: number }) => {
setNumPages(total) setNumPages(total)
setLoadError(null) setLoadError(null)
setPageError(null)
}, []) }, [])
const onDocumentLoadError = useCallback((error: Error) => { const onDocumentLoadError = useCallback((error: Error) => {
setLoadError(error.message) setLoadError(error.message)
}, []) }, [])
const onPageLoadError = useCallback((error: Error) => {
setPageError(error.message)
}, [])
const goToPrevPage = () => setPageNumber((prev) => Math.max(1, prev - 1)) const goToPrevPage = () => setPageNumber((prev) => Math.max(1, prev - 1))
const goToNextPage = () => setPageNumber((prev) => Math.min(numPages, prev + 1)) const goToNextPage = () => setPageNumber((prev) => Math.min(numPages, prev + 1))
const zoomIn = () => setZoomIndex((prev) => Math.min(ZOOM_LEVELS.length - 1, prev + 1)) const zoomIn = () => setZoomIndex((prev) => Math.min(ZOOM_LEVELS.length - 1, prev + 1))
@ -96,7 +102,10 @@ export const PdfViewerPage: React.FC = () => {
<div className="flex-1 overflow-auto flex justify-center p-4"> <div className="flex-1 overflow-auto flex justify-center p-4">
{loadError ? ( {loadError ? (
<div className="flex items-center justify-center h-full"> <div className="flex items-center justify-center h-full">
<p className="text-red-600">Failed to load PDF: {loadError}</p> <div className="text-center space-y-2">
<p className="text-red-600">Failed to load PDF: {loadError}</p>
<p className="text-sm text-gray-500">URL: {pdfUrl}</p>
</div>
</div> </div>
) : ( ) : (
<Document <Document
@ -110,6 +119,8 @@ export const PdfViewerPage: React.FC = () => {
scale={ZOOM_LEVELS[zoomIndex]} scale={ZOOM_LEVELS[zoomIndex]}
renderTextLayer={true} renderTextLayer={true}
renderAnnotationLayer={true} renderAnnotationLayer={true}
onLoadError={onPageLoadError}
error={<div className="text-red-600">Failed to load page: {pageError}</div>}
/> />
</Document> </Document>
)} )}