@nine-lab/nine-mu 0.1.343 โ 0.1.344
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/dist/nine-mu.js +50 -66
- package/dist/nine-mu.js.map +1 -1
- package/dist/nine-mu.umd.js +3 -3
- package/dist/nine-mu.umd.js.map +1 -1
- package/package.json +1 -1
- package/src/components/exception/ExceptionHook.js +52 -63
package/package.json
CHANGED
|
@@ -37,6 +37,9 @@ export class ExceptionHook extends HTMLElement {
|
|
|
37
37
|
window.onerror = this.#oldOnError;
|
|
38
38
|
trace.log("๐ [nine-exception-hook] window.onerror ๋ณต๊ตฌ ์๋ฃ");
|
|
39
39
|
}
|
|
40
|
+
|
|
41
|
+
// ํ๋ฉด ๋ฆฌ์
์ ๋ฐํ์๋ ๋ฐ๊นฅ์ชฝ ์๋ฌ ์ปจํ
์ด๋ ์ ๊ฑฐ
|
|
42
|
+
this.#removeExternalOverlay();
|
|
40
43
|
}
|
|
41
44
|
|
|
42
45
|
#setupGlobalSniffer() {
|
|
@@ -68,31 +71,16 @@ export class ExceptionHook extends HTMLElement {
|
|
|
68
71
|
#renderer = () => {
|
|
69
72
|
const customImport = nine.cssPath ? `@import "${nine.cssPath}/nine-mu.css";` : "";
|
|
70
73
|
|
|
71
|
-
// ๐ฏ [์์ 1] ๊ธ๋ก๋ฒ ๋ก๋ฉ ์ค๋ฒ๋ ์ด๋ฅผ ํ๋ฉด ์ ์ฒด์์ ์ฐ์ด๋๋ฅด๊ธฐ ์ํ ํธ์คํธ ๋ฐ ๋ ์ด์ด ์คํ์ผ ๋ด์ฅ
|
|
72
74
|
this.shadowRoot.innerHTML = `
|
|
73
75
|
<style>
|
|
74
76
|
@import "https://cdn.jsdelivr.net/npm/@nine-lab/nine-mu@${__APP_VERSION__}/dist/css/nine-mu.css";
|
|
75
77
|
${customImport}
|
|
76
|
-
|
|
77
78
|
:host {
|
|
78
79
|
display: block;
|
|
79
80
|
width: 100%;
|
|
80
81
|
height: 100%;
|
|
81
82
|
}
|
|
82
|
-
/* ์ด๋ค ๋ก๋ฉ ๋ ์ด์ด๊ฐ ๋๊ณ ์์ด๋ ๋ทฐํฌํธ ๊ธฐ์ค ๋ฌด์กฐ๊ฑด ๋งจ ์(์ต์๋จ)์ผ๋ก ๋นผ๋ฒ๋ฆฌ๋ ์ ๋ ๋ฐฉ์ด ํด๋์ค */
|
|
83
|
-
.nine-hook-full-overlay {
|
|
84
|
-
position: fixed !important;
|
|
85
|
-
top: 0 !important;
|
|
86
|
-
left: 0 !important;
|
|
87
|
-
width: 100vw !important;
|
|
88
|
-
height: 100vh !important;
|
|
89
|
-
box-sizing: border-box !important;
|
|
90
|
-
background-color: #FFF5F5 !important;
|
|
91
|
-
z-index: 99999999 !important;
|
|
92
|
-
overflow: auto !important;
|
|
93
|
-
}
|
|
94
83
|
</style>
|
|
95
|
-
|
|
96
84
|
<div class="nine-hook-core" style="width: 100%; height: 100%;">
|
|
97
85
|
<slot></slot>
|
|
98
86
|
</div>
|
|
@@ -112,19 +100,13 @@ export class ExceptionHook extends HTMLElement {
|
|
|
112
100
|
#handleRuntimeError = (event) => {
|
|
113
101
|
trace.log("๐จ [nine-exception-hook] window.addEventListener('error') ๋ฆฌ์ค๋ ํฌ์ฐฉ!!", event);
|
|
114
102
|
|
|
115
|
-
if (this.#hasError)
|
|
116
|
-
trace.log("โ ๏ธ [nine-exception-hook] ์ด๋ฏธ ์๋ฌ ํ๋ฉด์ด ํ์ฑํ๋์ด ์์ด ์ด๋ฒคํธ ๋ฆฌ์ค๋ ํจ์ค");
|
|
117
|
-
return;
|
|
118
|
-
}
|
|
103
|
+
if (this.#hasError) return;
|
|
119
104
|
|
|
120
105
|
const errorMessage = event.error?.message || event.message || String(event);
|
|
121
106
|
const errorStack = event.error?.stack || "No stack trace available";
|
|
122
107
|
|
|
123
108
|
if (errorMessage && errorMessage !== "Script error.") {
|
|
124
|
-
trace.log("๐ฏ [nine-exception-hook] ์ ์์ ์ธ ์๋ฌ ๋ฉ์์ง ํ์ธ -> ์๋ฌ ๋ณด๋ ์ถ๋ ฅ ์๋", { errorMessage });
|
|
125
109
|
this.#renderError(errorMessage, errorStack);
|
|
126
|
-
} else {
|
|
127
|
-
trace.log("โ ๏ธ [nine-exception-hook] 'Script error.' ์ด๊ฑฐ๋ ๋น ๋ฉ์์ง๋ผ ๋ฌด์๋จ");
|
|
128
110
|
}
|
|
129
111
|
}
|
|
130
112
|
|
|
@@ -137,36 +119,34 @@ export class ExceptionHook extends HTMLElement {
|
|
|
137
119
|
const errorMessage = reason?.message || String(reason || "Unhandled Promise Rejection");
|
|
138
120
|
const errorStack = reason?.stack || "No stack trace available";
|
|
139
121
|
|
|
140
|
-
trace.log("๐ฏ [nine-exception-hook] Promise ๊ฑฐ๋ถ ํ์ธ -> ์๋ฌ ๋ณด๋ ์ถ๋ ฅ ์๋");
|
|
141
122
|
this.#renderError(errorMessage, errorStack);
|
|
142
123
|
}
|
|
143
124
|
|
|
144
125
|
#handleLocationChange = () => {
|
|
145
126
|
setTimeout(() => {
|
|
146
|
-
trace.log("๐ [nine-exception-hook] ์ฃผ์ ์ด๋ ๊ฐ์ง ์ฒดํฌ", {
|
|
147
|
-
hasError: this.#hasError,
|
|
148
|
-
lastPath: this.#lastPath,
|
|
149
|
-
currentPath: window.location.pathname
|
|
150
|
-
});
|
|
151
|
-
|
|
152
127
|
if (this.#hasError && this.#lastPath !== window.location.pathname) {
|
|
153
|
-
trace.log("โจ [nine-exception-hook] Shadow DOM ๋ด๋ถ ์์ธ ์ฒญ์ ๋ฐ ์ ์ ๋ณต๊ตฌ");
|
|
128
|
+
trace.log("โจ [nine-exception-hook] Shadow DOM ๋ฐ ๊ธ๋ก๋ฒ ์ค๋ฒ๋ ์ด ๋ด๋ถ ์์ธ ์ฒญ์ ๋ฐ ์ ์ ๋ณต๊ตฌ");
|
|
154
129
|
this.#lastPath = window.location.pathname;
|
|
155
130
|
this.#hasError = false;
|
|
156
131
|
|
|
157
|
-
|
|
158
|
-
if (exceptionBoard) exceptionBoard.innerHTML = '';
|
|
132
|
+
this.#removeExternalOverlay();
|
|
159
133
|
|
|
160
134
|
const coreContainer = this.shadowRoot.querySelector('.nine-hook-core');
|
|
161
135
|
if (coreContainer) coreContainer.style.display = '';
|
|
162
136
|
}
|
|
163
|
-
}, 50);
|
|
137
|
+
}, 50);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
#removeExternalOverlay() {
|
|
141
|
+
const target = document.getElementById('nine-global-exception-container');
|
|
142
|
+
if (target) target.remove();
|
|
164
143
|
}
|
|
165
144
|
|
|
166
145
|
#sendToAiAction = async (errorMessage, errorStack) => {
|
|
167
|
-
|
|
168
|
-
const
|
|
169
|
-
const
|
|
146
|
+
// ๊ธ๋ก๋ฒ ์๋ฆฌ๋จผํธ ๋ด์์ ํ์ํ๋๋ก ๋ณ๊ฒฝ
|
|
147
|
+
const root = document.getElementById('nine-global-exception-container') || this.shadowRoot;
|
|
148
|
+
const btn = root.querySelector('.nine-ai-btn');
|
|
149
|
+
const footer = root.querySelector('.nine-error-footer');
|
|
170
150
|
if (!btn) return;
|
|
171
151
|
|
|
172
152
|
btn.disabled = true;
|
|
@@ -175,7 +155,6 @@ export class ExceptionHook extends HTMLElement {
|
|
|
175
155
|
|
|
176
156
|
try {
|
|
177
157
|
if (window.triggerAutoRecovery) {
|
|
178
|
-
trace.log("๐ก [nine-exception-hook] window.triggerAutoRecovery ํธ์ถ ์คํ");
|
|
179
158
|
await window.triggerAutoRecovery({
|
|
180
159
|
message: errorMessage,
|
|
181
160
|
stack: errorStack || "No stack trace available",
|
|
@@ -200,42 +179,52 @@ export class ExceptionHook extends HTMLElement {
|
|
|
200
179
|
this.#hasError = true;
|
|
201
180
|
|
|
202
181
|
setTimeout(() => {
|
|
203
|
-
trace.log("๐จ [nine-exception-hook] ๋ฆฌ์กํธ ์ฌ์ดํด ์ข
๋ฃ ํ ์๋ฌ
|
|
182
|
+
trace.log("๐จ [nine-exception-hook] ๋ฆฌ์กํธ ์ฌ์ดํด ์ข
๋ฃ ํ ์ต์๋จ ๊ธ๋ก๋ฒ ์๋ฌ ๋ ์ด์ด ์์ฑ");
|
|
204
183
|
|
|
205
184
|
const coreContainer = this.shadowRoot.querySelector('.nine-hook-core');
|
|
206
|
-
if (coreContainer)
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
185
|
+
if (coreContainer) coreContainer.style.display = 'none';
|
|
186
|
+
|
|
187
|
+
// ๐ฏ [ํต์ฌ ๋ณ๊ฒฝ] Shadow DOM ๋ด๋ถ๊ฐ ์๋๋ผ document.body์ ์ง์ fixed ์ปจํ
์ด๋๋ฅผ ๊ฝ์๋ฒ๋ ค
|
|
188
|
+
// global-loading-overlay๋ฅผ ์๋ฒฝํ ๋ฎ์ด๋ฒ๋ฆฝ๋๋ค.
|
|
189
|
+
this.#removeExternalOverlay();
|
|
190
|
+
|
|
191
|
+
const externalContainer = document.createElement('div');
|
|
192
|
+
externalContainer.id = 'nine-global-exception-container';
|
|
193
|
+
|
|
194
|
+
// ์ธ๋ผ์ธ ์คํ์ผ๋ก ์ธ๋ถ ์์๋ฅผ ์์ ํ ์ฐจ๋จํ๊ณ ๋งจ ์์ผ๋ก ๋ฐฐ์น
|
|
195
|
+
Object.assign(externalContainer.style, {
|
|
196
|
+
position: 'fixed',
|
|
197
|
+
top: '0',
|
|
198
|
+
left: '0',
|
|
199
|
+
width: '100vw',
|
|
200
|
+
height: '100vh',
|
|
201
|
+
backgroundColor: '#FFF5F5',
|
|
202
|
+
zIndex: '2147483647', // ๋ธ๋ผ์ฐ์ ํํ ์ต๋ z-index ๊ฐ ๋ถ์ฌ
|
|
203
|
+
overflow: 'auto',
|
|
204
|
+
boxSizing: 'border-box',
|
|
205
|
+
display: 'block'
|
|
206
|
+
});
|
|
216
207
|
|
|
217
|
-
// ๐ฏ [์์ 2] ์๋ฌ HTML ์ปจํ
์ด๋ ๊ตฌ์กฐ๋ฅผ ํ๋ฉด ์ ์ฒด ๋ทฐํฌํธ๋ฅผ ์ฅ์
ํ๋ ๊ณ ์ ๋ ์ด์์ ๊ตฌ์กฐ๋ก ๋ฉํ
|
|
218
208
|
const errorHTML = `
|
|
219
|
-
<div class="nine-
|
|
220
|
-
<
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
<
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
๋ฒํผ์ ๋๋ฅด๋ฉด AI๊ฐ ๋ก๊ทธ ๋ฐ ์ปดํฌ๋ํธ ๋งต์ ์ญ์ถ์ ํ์ฌ ์์ ์ ์์ํฉ๋๋ค.
|
|
229
|
-
</div>
|
|
209
|
+
<div class="nine-error-container" style="padding: 40px; max-width: 1200px; margin: 40px auto; font-family: sans-serif; background: white; border-radius: 8px; box-shadow: 0 10px 25px rgba(0,0,0,0.08); text-align: left;">
|
|
210
|
+
<h3 class="nine-error-title" style="color: #C53030; margin-top: 0; font-size: 22px; font-weight: 700; border-bottom: 2px solid #FED2D2; padding-bottom: 12px; font-family: sans-serif;">โ ๏ธ ์์คํ
์์ธ ๊ฐ์ง (nine-exception-hook)</h3>
|
|
211
|
+
<p class="nine-error-label" style="font-weight: bold; margin: 20px 0 8px 0; color: #4A5568; font-size: 15px; font-family: sans-serif;">[์๋ฌ ์์ธ ๋ก๊ทธ]:</p>
|
|
212
|
+
<pre class="nine-error-log" style="background: #1A202C; color: #EDF2F7; padding: 20px; border-radius: 6px; overflow-x: auto; white-space: pre-wrap; font-family: monospace; font-size: 14px; line-height: 1.6; margin-bottom: 25px;">${errorMessage}\n\n[Stack Trace]\n${errorStack}</pre>
|
|
213
|
+
|
|
214
|
+
<div class="nine-action-area" style="display: flex; align-items: center; gap: 20px; border-top: 1px solid #E2E8F0; padding-top: 20px;">
|
|
215
|
+
<button class="nine-ai-btn" style="background: #3182CE; color: white; border: none; padding: 14px 28px; border-radius: 6px; font-weight: bold; cursor: pointer; font-size: 16px;">๐ค AI์๊ฒ ์์ค์ฝ๋ ์์ ์์ฒญ</button>
|
|
216
|
+
<div class="nine-error-footer" style="font-size: 14px; color: #718096; line-height: 1.4; font-family: sans-serif;">
|
|
217
|
+
๋ฒํผ์ ๋๋ฅด๋ฉด AI๊ฐ ๋ก๊ทธ ๋ฐ ์ปดํฌ๋ํธ ๋งต์ ์ญ์ถ์ ํ์ฌ ์์ ์ ์์ํฉ๋๋ค.
|
|
230
218
|
</div>
|
|
231
219
|
</div>
|
|
232
220
|
</div>
|
|
233
221
|
`;
|
|
234
222
|
|
|
235
|
-
|
|
236
|
-
|
|
223
|
+
externalContainer.innerHTML = errorHTML;
|
|
224
|
+
document.body.appendChild(externalContainer);
|
|
225
|
+
trace.log("๐จ [nine-exception-hook] ๋ธ๋ผ์ฐ์ Body ์ต์๋จ ๋ ์ด์ด ๋ฐฐ์ ์ฑ๊ณต");
|
|
237
226
|
|
|
238
|
-
const aiBtn =
|
|
227
|
+
const aiBtn = externalContainer.querySelector('.nine-ai-btn');
|
|
239
228
|
if (aiBtn) {
|
|
240
229
|
aiBtn.addEventListener('click', () => this.#sendToAiAction(errorMessage, errorStack));
|
|
241
230
|
trace.log("๐จ [nine-exception-hook] AI ์์ฒญ ๋ฒํผ ์ด๋ฒคํธ ๋ฆฌ์ค๋ ์ต์ข
๋ฐ์ธ๋ฉ ์ฑ๊ณต");
|