@nine-lab/nine-mu 0.1.358 → 0.1.360
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -5,11 +5,10 @@ import React from 'react';
|
|
|
5
5
|
// ==========================================
|
|
6
6
|
export const NineExceptionStyles = {
|
|
7
7
|
container: {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
borderRadius: '6px',
|
|
8
|
+
minHeight: '100%',
|
|
9
|
+
flexGrow: 1,
|
|
10
|
+
padding: '25px',
|
|
11
|
+
background: '#121314',
|
|
13
12
|
// ⭐ 모든 요소가 완벽한 터미널 정렬을 갖추도록 고정폭 서체를 부모에 강제 주입
|
|
14
13
|
fontFamily: 'Consolas, Monaco, "Courier New", monospace',
|
|
15
14
|
textAlign: 'left',
|
|
@@ -31,7 +30,7 @@ export const NineExceptionStyles = {
|
|
|
31
30
|
},
|
|
32
31
|
pre: {
|
|
33
32
|
background: 'transparent',
|
|
34
|
-
color: '#
|
|
33
|
+
color: '#666',
|
|
35
34
|
padding: '0',
|
|
36
35
|
margin: '0', // pre 태그 고유의 불규칙한 여백 완전 제거
|
|
37
36
|
border: 'none',
|
|
@@ -88,6 +87,11 @@ export class NineExceptionHook extends React.Component {
|
|
|
88
87
|
|
|
89
88
|
componentDidCatch(error, errorInfo) {
|
|
90
89
|
console.error("🚨 [Nine-Library] 본문 렌더링 에러 포착:", error);
|
|
90
|
+
|
|
91
|
+
this.setState({
|
|
92
|
+
errorInfo: errorInfo || null
|
|
93
|
+
});
|
|
94
|
+
|
|
91
95
|
if (this.props.onCatch) {
|
|
92
96
|
this.props.onCatch(error, errorInfo);
|
|
93
97
|
}
|
|
@@ -116,7 +120,8 @@ export class NineExceptionHook extends React.Component {
|
|
|
116
120
|
|
|
117
121
|
handleLocationChange() {
|
|
118
122
|
setTimeout(() => {
|
|
119
|
-
|
|
123
|
+
// reportStatus 조건 대신, 에러가 나 있는 상태에서 주소가 바뀌었는지만 체크해야 안전합니다.
|
|
124
|
+
if (this.state.hasError && this.lastPath !== window.location.pathname) {
|
|
120
125
|
console.log("[Nine-Library] 페이지 주소 변경 감지 -> 에러 상태 초기화");
|
|
121
126
|
this.lastPath = window.location.pathname;
|
|
122
127
|
this.setState({ hasError: false, error: null, reportStatus: 'idle' });
|
|
@@ -149,6 +154,22 @@ export class NineExceptionHook extends React.Component {
|
|
|
149
154
|
const errorMessage = this.state.error?.message || String(this.state.error);
|
|
150
155
|
const customStyles = this.props.styles || {};
|
|
151
156
|
|
|
157
|
+
// 🔍 React 컴포넌트 스택에서 파일명과 라인 번호 추출기
|
|
158
|
+
let errorLocation = '';
|
|
159
|
+
if (this.state.errorInfo?.componentStack) {
|
|
160
|
+
// 스택 트레이스 문자열에서 실제 파일 경로가 포함된 첫 줄을 타겟팅합니다.
|
|
161
|
+
const lines = this.state.errorInfo.componentStack.trim().split('\n');
|
|
162
|
+
const targetLine = lines[0] || '';
|
|
163
|
+
|
|
164
|
+
// 정규식을 이용해 파일명과 라인 번호 정제 (예: at UserList (at users.js:42) -> UserList (users.js:42))
|
|
165
|
+
const match = targetLine.match(/at\s+(\w+)\s+\((.*)\)/) || targetLine.match(/at\s+(.*)/);
|
|
166
|
+
if (match) {
|
|
167
|
+
errorLocation = match[2] ? `${match[1]} (${match[2]})` : match[1];
|
|
168
|
+
} else {
|
|
169
|
+
errorLocation = targetLine.trim();
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
152
173
|
return React.createElement(
|
|
153
174
|
'div',
|
|
154
175
|
{
|
|
@@ -162,10 +183,17 @@ export class NineExceptionHook extends React.Component {
|
|
|
162
183
|
'[SYSTEM] COMPONENT RENDER ERROR DETECTED'
|
|
163
184
|
),
|
|
164
185
|
|
|
165
|
-
// 2. 에러 내용
|
|
186
|
+
// 2. 에러 내용 (aa is not defined)
|
|
166
187
|
React.createElement('pre', { style: { ...NineExceptionStyles.pre, ...customStyles.pre } }, errorMessage),
|
|
167
188
|
|
|
168
|
-
// 3.
|
|
189
|
+
// ⭐ 3. [추가] 파싱된 에러 발생 파일명 및 라인 위치 (터미널 그레이 색상 매칭)
|
|
190
|
+
errorLocation && React.createElement(
|
|
191
|
+
'div',
|
|
192
|
+
{ style: { color: '#666', fontSize: '14px', margin: '0 0 12px 0', fontFamily: 'Consolas, Monaco, monospace', lineHeight: '1' } },
|
|
193
|
+
` at ${errorLocation}`
|
|
194
|
+
),
|
|
195
|
+
|
|
196
|
+
// 4. CLI 프롬프트 영역
|
|
169
197
|
React.createElement(
|
|
170
198
|
'div',
|
|
171
199
|
{ style: { ...NineExceptionStyles.footer, ...customStyles.footer } },
|