feat: add AttireErrorBoundary component for improved error handling in attire model loading
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
'use client';
|
||||
|
||||
import { useRef, useMemo, useEffect, Suspense, useState } from 'react';
|
||||
import { useRef, useMemo, useEffect, Suspense, useState, Component, type ReactNode } from 'react';
|
||||
import { useGLTF } from '@react-three/drei';
|
||||
import { useFrame } from '@react-three/fiber';
|
||||
import * as THREE from 'three';
|
||||
@@ -24,6 +24,30 @@ function buildAttireGlbMap(personas: { id: string; modelPath?: string }[]): Reco
|
||||
return { ...STATIC_ATTIRE_GLB, ...dynamic }; // uploaded GLBs override static
|
||||
}
|
||||
|
||||
interface AttireErrorBoundaryProps {
|
||||
children: ReactNode;
|
||||
onError: () => void;
|
||||
}
|
||||
interface AttireErrorBoundaryState { hasError: boolean; }
|
||||
|
||||
class AttireErrorBoundary extends Component<AttireErrorBoundaryProps, AttireErrorBoundaryState> {
|
||||
constructor(props: AttireErrorBoundaryProps) {
|
||||
super(props);
|
||||
this.state = { hasError: false };
|
||||
}
|
||||
static getDerivedStateFromError(): AttireErrorBoundaryState {
|
||||
return { hasError: true };
|
||||
}
|
||||
componentDidCatch(error: Error) {
|
||||
console.warn('[AttireModel] Failed to load GLB, falling back to base robot:', error.message);
|
||||
this.props.onError();
|
||||
}
|
||||
render() {
|
||||
if (this.state.hasError) return null;
|
||||
return this.props.children;
|
||||
}
|
||||
}
|
||||
|
||||
function easeInOutCubic(t: number): number {
|
||||
return t < 0.5
|
||||
? 4 * t * t * t
|
||||
@@ -205,13 +229,14 @@ export function RobotModel({ onError }: RobotModelProps) {
|
||||
<primitive object={processedScene} />
|
||||
|
||||
{attireGlbPath && (
|
||||
<Suspense fallback={null}>
|
||||
<AttireModel
|
||||
key={attireGlbPath}
|
||||
glbPath={attireGlbPath}
|
||||
onLoaded={handleAttireLoaded}
|
||||
/>
|
||||
</Suspense>
|
||||
<AttireErrorBoundary key={attireGlbPath} onError={() => { setDisplayedAttire('none'); setAttireReady(false); }}>
|
||||
<Suspense fallback={null}>
|
||||
<AttireModel
|
||||
glbPath={attireGlbPath}
|
||||
onLoaded={handleAttireLoaded}
|
||||
/>
|
||||
</Suspense>
|
||||
</AttireErrorBoundary>
|
||||
)}
|
||||
</group>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user