diff --git a/dicom-viewer/src/App.tsx b/dicom-viewer/src/App.tsx index 12aed99..d4a5893 100644 --- a/dicom-viewer/src/App.tsx +++ b/dicom-viewer/src/App.tsx @@ -434,6 +434,45 @@ function App({ container_id, imageStacks, autoCacheStack, annotationJson, viewer const [stackOrderModified, setStackOrderModified] = useState(false); const [loadingState, setLoadingState] = useState(null); + // Show a warning when a WebGL/graphics resource error (e.g. releaseGraphicsResources) occurs + const [graphicsErrorVisible, setGraphicsErrorVisible] = useState(false); + const [graphicsErrorMessage, setGraphicsErrorMessage] = useState(null); + + useEffect(() => { + const onError = (ev: ErrorEvent) => { + try { + const msg = ev && ev.message ? String(ev.message) : ''; + if (msg.includes('releaseGraphicsResources') || msg.includes('openGLTexture')) { + console.error('Detected graphics resource error:', ev); + setGraphicsErrorMessage(msg || null); + setGraphicsErrorVisible(true); + } + } catch (e) { + // ignore + } + }; + + const onRejection = (ev: PromiseRejectionEvent) => { + try { + const reason = (ev && (ev as any).reason) || ''; + const text = typeof reason === 'string' ? reason : (reason && reason.message) ? reason.message : String(reason); + if (text.includes('releaseGraphicsResources') || text.includes('openGLTexture')) { + console.error('Detected graphics resource rejection:', ev); + setGraphicsErrorMessage(text || null); + setGraphicsErrorVisible(true); + } + } catch (e) { + // ignore + } + }; + + window.addEventListener('error', onError as EventListener); + window.addEventListener('unhandledrejection', onRejection as EventListener); + return () => { + window.removeEventListener('error', onError as EventListener); + window.removeEventListener('unhandledrejection', onRejection as EventListener); + }; + }, []); // Load annotations and viewer state from props if provided useEffect(() => { let didCancel = false; @@ -3578,6 +3617,37 @@ function App({ container_id, imageStacks, autoCacheStack, annotationJson, viewer )} + {/* Graphics error banner (shows when we detect a problematic WebGL release error) */} + {graphicsErrorVisible && ( +
+
+ Graphics error: The viewer encountered a WebGL/graphics error and may be unstable. Please reload the page. + {graphicsErrorMessage ? (
{graphicsErrorMessage}
) : null} +
+
+ + +
+
+ )} + {/* top stack bar removed; use right-side panel instead */} {/* Right-side stack panel is implemented in the main content flex container below */}