์ปจํ
์คํธ ๋ธ๋ก
| Key |
Value |
| Category |
frontend |
| Checklist |
ISS-UI-R8 โ Missing React error boundaries for client-side crashes |
| Priority |
P2 ๐ก |
| Scan Date |
2026-04-16 |
| Flagged By |
@code-review |
์์ฝ
- WHAT:
frontend/src/shared/components/ErrorBoundary.tsx์ generic ErrorBoundary ์ ์๋์ด ์์ผ๋ app/layout.tsx๋ MainLayoutClient.tsx์์ ๋ง์ดํธ๋์ง ์์. ThreadErrorBoundary๋ง thread view ๋ด๋ถ์ ์ฌ์ฉ
- WHY:
StreamProvider, AssistantConfigProvider ๋ฑ client-side provider tree์์ ๋ฐ์ํ๋ ํฌ๋์๊ฐ ์บ์น๋์ง ์์ ์ ์ฒด ํ์ด์ง white screen
- WHERE:
frontend/src/shared/components/ErrorBoundary.tsx (์ ์), frontend/src/app/layout.tsx / frontend/src/shared/components/layout/MainLayoutClient.tsx (๋ฏธ์ฌ์ฉ)
- SEVERITY: MEDIUM โ ๋ถ๋ถ ํฌ๋์ ์ ์ ์ฒด ํ๋ฉด ๊นจ์ง (UX ์ ํ), ๊ธฐ์กด #61๊ณผ ๋ณด์์
Evidence
| # |
File |
Line |
Finding |
Flagged By |
Confidence |
| 1 |
frontend/src/shared/components/ErrorBoundary.tsx |
โ |
generic ErrorBoundary ์ปดํฌ๋ํธ ์ ์ |
@code-review |
High |
| 2 |
frontend/src/app/layout.tsx |
โ |
ErrorBoundary import / ์ฌ์ฉ ์์ |
@code-review |
High |
| 3 |
frontend/src/shared/components/layout/MainLayoutClient.tsx |
โ |
ErrorBoundary import / ์ฌ์ฉ ์์ |
@code-review |
High |
| 4 |
frontend/src/features/chat/components/ThreadErrorBoundary.tsx |
โ |
Thread ์ ์ฉ ErrorBoundary, ThreadContent ๋ด๋ถ์๋ง ์ ์ฉ |
@code-review |
High |
์ํฅ ๋ถ์
์ํฅ ๋ฒ์
- ์ฑํ
์ธ ์์ญ์ ๋ชจ๋ client provider ํฌ๋์ (Settings, AssistantConfig, AuthProvider ๋ฑ)
- StreamProvider ๋ด๋ถ์ SSE ์ฒ๋ฆฌ ์๋ฌ
- ๋ผ์ฐํ
์ ํ ์ค ๋ฏธ์บ์น ์๋ฌ
์ฅ์ ์๋๋ฆฌ์ค
- ์ฌ์ฉ์ ๋ก๊ทธ์ธ ํ chat ํ์ด์ง ์ ๊ทผ
- AssistantConfigProvider๊ฐ ์๋ชป๋ ์๋ต์ผ๋ก throw
- ThreadErrorBoundary ๋ฒ์ ์ธ๋ถ์ด๋ฏ๋ก ์ ํ โ React 16+ ๊ธฐ๋ณธ ๋์์ผ๋ก unmount ํ white screen
- ์ฌ์ฉ์๋ ์๋ก๊ณ ์นจ ์ธ ๋ณต๊ตฌ ๋ถ๊ฐ
๊ธด๊ธ๋
- ๊ธฐ์กด ์ด์ #61์ด Next.js์
error.tsx ๋ผ์ฐํธ boundary๋ฅผ ๋ค๋ฃธ โ ์ด๋ server/render ๋จ๊ณ
- ๋ณธ ์ด์๋ React component-tree ๋ ๋ฒจ์ client-side runtime ์๋ฌ๋ฅผ ๋ค๋ฃธ โ ์๋ณด์ , ๋ ๋ค ํ์
์ ์ ํด๊ฒฐ ๋ฐฉ์
์ ๊ทผ ๋ฐฉ๋ฒ
MainLayoutClient.tsx ๋๋ app/layout.tsx์์ provider tree ์ ์ฒด๋ฅผ ErrorBoundary๋ก ๊ฐ์ธ๊ธฐ:
// frontend/src/shared/components/layout/MainLayoutClient.tsx
import { ErrorBoundary } from \"@/shared/components/ErrorBoundary\";
export function MainLayoutClient({ children }: Props) {
return (
<ErrorBoundary
fallback={(error) => <RootErrorFallback error={error} />}
onError={(error, info) => {
console.error(\"[root] uncaught\", error, info);
// ์ต์
: Sentry, LogRocket ๋ฑ ์ธ๋ถ ๋ชจ๋ํฐ๋ง ์ ์ก
}}
>
<SessionProvider>
<AuthProvider>
<SettingsProvider>
<AssistantConfigProvider>
{children}
</AssistantConfigProvider>
</SettingsProvider>
</AuthProvider>
</SessionProvider>
</ErrorBoundary>
);
}
RootErrorFallback์ "์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค / ์๋ก๊ณ ์นจ" ๋ฉ์์ง + reload ๋ฒํผ + ์๋ฌ ์ฝ๋ ํ์.
๋์
์์ฉ ๊ธฐ์ค
์ฐธ์กฐ
์ฌํ ๋ฐฉ๋ฒ
์ฌ์ ์กฐ๊ฑด
๋จ๊ณ
- AssistantConfigProvider์ ์๋์ throw ์ฝ์
(ํ
์คํธ์ฉ)
- ํ์ด์ง ๋ก๋
- UI ์๋ต ํ์ธ
๊ธฐ๋ ๊ฒฐ๊ณผ
ErrorBoundary fallback UI ํ์
์ค์ ๊ฒฐ๊ณผ
React unmount โ white screen, console์ uncaught error
๊ด๋ จ ์ฝ๋ ์ปจํ
์คํธ
| File |
Role |
Relevance |
frontend/src/shared/components/ErrorBoundary.tsx |
Generic ErrorBoundary ์ปดํฌ๋ํธ |
ํ์ฉ ๋์ |
frontend/src/shared/components/layout/MainLayoutClient.tsx |
Client root layout |
์์ ๋์ |
frontend/src/features/chat/components/ThreadErrorBoundary.tsx |
Thread ์ ์ฉ boundary |
์ฐธ๊ณ ํจํด |
Detected by oh-my-braincrew `omb:issue` scan
Category: frontend | Scan date: 2026-04-16
`omb-issue-scan category=frontend checklist=ISS-UI-R8`
์ปจํ ์คํธ ๋ธ๋ก
ISS-UI-R8โ Missing React error boundaries for client-side crashes์์ฝ
frontend/src/shared/components/ErrorBoundary.tsx์ generic ErrorBoundary ์ ์๋์ด ์์ผ๋app/layout.tsx๋MainLayoutClient.tsx์์ ๋ง์ดํธ๋์ง ์์.ThreadErrorBoundary๋ง thread view ๋ด๋ถ์ ์ฌ์ฉStreamProvider,AssistantConfigProvider๋ฑ client-side provider tree์์ ๋ฐ์ํ๋ ํฌ๋์๊ฐ ์บ์น๋์ง ์์ ์ ์ฒด ํ์ด์ง white screenfrontend/src/shared/components/ErrorBoundary.tsx(์ ์),frontend/src/app/layout.tsx/frontend/src/shared/components/layout/MainLayoutClient.tsx(๋ฏธ์ฌ์ฉ)Evidence
frontend/src/shared/components/ErrorBoundary.tsxfrontend/src/app/layout.tsxfrontend/src/shared/components/layout/MainLayoutClient.tsxfrontend/src/features/chat/components/ThreadErrorBoundary.tsxThreadContent๋ด๋ถ์๋ง ์ ์ฉ์ํฅ ๋ถ์
์ํฅ ๋ฒ์
์ฅ์ ์๋๋ฆฌ์ค
๊ธด๊ธ๋
error.tsx๋ผ์ฐํธ boundary๋ฅผ ๋ค๋ฃธ โ ์ด๋ server/render ๋จ๊ณ์ ์ ํด๊ฒฐ ๋ฐฉ์
์ ๊ทผ ๋ฐฉ๋ฒ
MainLayoutClient.tsx๋๋app/layout.tsx์์ provider tree ์ ์ฒด๋ฅผ ErrorBoundary๋ก ๊ฐ์ธ๊ธฐ:RootErrorFallback์ "์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค / ์๋ก๊ณ ์นจ" ๋ฉ์์ง + reload ๋ฒํผ + ์๋ฌ ์ฝ๋ ํ์.๋์
์์ฉ ๊ธฐ์ค
MainLayoutClient.tsx์์ ErrorBoundary๋ก provider tree ๊ฐ์ธ๊ธฐcd frontend && pnpm test์ฐธ์กฐ
frontend/src/shared/components/ErrorBoundary.tsx,frontend/src/shared/components/layout/MainLayoutClient.tsx,frontend/src/app/layout.tsx์ฌํ ๋ฐฉ๋ฒ
์ฌ์ ์กฐ๊ฑด
๋จ๊ณ
๊ธฐ๋ ๊ฒฐ๊ณผ
ErrorBoundary fallback UI ํ์
์ค์ ๊ฒฐ๊ณผ
React unmount โ white screen, console์ uncaught error
๊ด๋ จ ์ฝ๋ ์ปจํ ์คํธ
frontend/src/shared/components/ErrorBoundary.tsxfrontend/src/shared/components/layout/MainLayoutClient.tsxfrontend/src/features/chat/components/ThreadErrorBoundary.tsx