@nine-lab/nine-mu 0.1.344 โ 0.1.345
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 +51 -67
- 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 +48 -75
package/package.json
CHANGED
|
@@ -11,14 +11,11 @@ export class ExceptionHook extends HTMLElement {
|
|
|
11
11
|
constructor() {
|
|
12
12
|
super();
|
|
13
13
|
this.attachShadow({ mode: 'open' });
|
|
14
|
-
trace.log("๐ [nine-exception-hook] ์ธ์คํด์ค ์์ฑ๋จ");
|
|
15
14
|
}
|
|
16
15
|
|
|
17
16
|
connectedCallback() {
|
|
18
|
-
trace.log("๐ [nine-exception-hook] DOM์ ๋ง์ดํธ๋จ. ์ด๋ฒคํธ ๋ฆฌ์ค๋ ๋ฐ์ธ๋ฉ ์์");
|
|
19
17
|
this.#renderer();
|
|
20
18
|
this.#injectShadowStylesheet();
|
|
21
|
-
|
|
22
19
|
this.#setupGlobalSniffer();
|
|
23
20
|
|
|
24
21
|
window.addEventListener('unhandledrejection', this.#handlePromiseError, true);
|
|
@@ -27,7 +24,6 @@ export class ExceptionHook extends HTMLElement {
|
|
|
27
24
|
}
|
|
28
25
|
|
|
29
26
|
disconnectedCallback() {
|
|
30
|
-
trace.log("๐ [nine-exception-hook] DOM์์ ์ธ๋ง์ดํธ๋จ. ๋ฆฌ์ค๋ ํด์ ");
|
|
31
27
|
window.removeEventListener('error', this.#handleRuntimeError, true);
|
|
32
28
|
window.removeEventListener('unhandledrejection', this.#handlePromiseError, true);
|
|
33
29
|
window.removeEventListener('popstate', this.#handleLocationChange);
|
|
@@ -35,56 +31,67 @@ export class ExceptionHook extends HTMLElement {
|
|
|
35
31
|
|
|
36
32
|
if (window.onerror === this.#handleRuntimeError || this.#oldOnError) {
|
|
37
33
|
window.onerror = this.#oldOnError;
|
|
38
|
-
trace.log("๐ [nine-exception-hook] window.onerror ๋ณต๊ตฌ ์๋ฃ");
|
|
39
34
|
}
|
|
40
|
-
|
|
41
|
-
// ํ๋ฉด ๋ฆฌ์
์ ๋ฐํ์๋ ๋ฐ๊นฅ์ชฝ ์๋ฌ ์ปจํ
์ด๋ ์ ๊ฑฐ
|
|
42
|
-
this.#removeExternalOverlay();
|
|
43
35
|
}
|
|
44
36
|
|
|
45
37
|
#setupGlobalSniffer() {
|
|
46
38
|
window.addEventListener('error', this.#handleRuntimeError, true);
|
|
47
|
-
trace.log("๐ [nine-exception-hook] window.addEventListener('error') ๋ฑ๋ก ์๋ฃ");
|
|
48
39
|
|
|
49
40
|
this.#oldOnError = window.onerror;
|
|
50
41
|
window.onerror = (message, source, lineno, colno, error) => {
|
|
51
|
-
trace.log("๐จ [nine-exception-hook] ์์ window.onerror ํฌ์ฐฉ!!", { message, source, lineno, error });
|
|
52
|
-
|
|
53
42
|
if (!this.#hasError) {
|
|
54
|
-
trace.log("๐ฏ [nine-exception-hook] ํ์ฌ ์๋ฌ ์ํ ์์ -> ์๋ฌ ๋ณด๋ ์ถ๋ ฅ ์๋");
|
|
55
43
|
const errorMessage = error?.message || message || "์ ์ ์๋ ๋ฐํ์ ์์ธ";
|
|
56
44
|
const errorStack = error?.stack || `${source}:${lineno}:${colno}`;
|
|
57
45
|
this.#renderError(errorMessage, errorStack);
|
|
58
|
-
} else {
|
|
59
|
-
trace.log("โ ๏ธ [nine-exception-hook] ์ด๋ฏธ ์๋ฌ ํ๋ฉด์ด ํ์ฑํ๋์ด ์์ด ์์ onerror ํจ์ค");
|
|
60
46
|
}
|
|
61
|
-
|
|
62
47
|
if (this.#oldOnError) {
|
|
63
|
-
trace.log("๐ [nine-exception-hook] ๊ธฐ์กด์ ๋ฑ๋ก๋์ด ์๋ ๋ค๋ฅธ onerror ์์ง์ผ๋ก ์์");
|
|
64
48
|
return this.#oldOnError(message, source, lineno, colno, error);
|
|
65
49
|
}
|
|
66
50
|
return false;
|
|
67
51
|
};
|
|
68
|
-
trace.log("๐ [nine-exception-hook] ์์ window.onerror ๊ฐ๋ก์ฑ๊ธฐ(Chaining) ์๋ฃ");
|
|
69
52
|
}
|
|
70
53
|
|
|
71
54
|
#renderer = () => {
|
|
72
55
|
const customImport = nine.cssPath ? `@import "${nine.cssPath}/nine-mu.css";` : "";
|
|
73
56
|
|
|
57
|
+
// ๐ฏ [ํต์ฌ ๋ณ๊ฒฝ 1] :host ์์ฒด๋ฅผ absolute์ ๊ธฐ์ค์ ์ด ๋๋ block์ผ๋ก ์ก๊ณ ,
|
|
58
|
+
// ๋ฆฌ์กํธ ์ฌ๋กฏ ๋ด์ฉ๋ฌผ(๋ฉ๋ด ๋ฑ)์ ์ ๋ ์จ๊ธฐ์ง ์๊ณ 100% ํฌ๊ธฐ๋ก ์ ์งํฉ๋๋ค.
|
|
74
59
|
this.shadowRoot.innerHTML = `
|
|
75
60
|
<style>
|
|
76
61
|
@import "https://cdn.jsdelivr.net/npm/@nine-lab/nine-mu@${__APP_VERSION__}/dist/css/nine-mu.css";
|
|
77
62
|
${customImport}
|
|
63
|
+
|
|
78
64
|
:host {
|
|
79
65
|
display: block;
|
|
80
66
|
width: 100%;
|
|
81
67
|
height: 100%;
|
|
68
|
+
position: relative !important; /* ๋ด๋ถ ์๋ฌ ๋ณด๋์ ๊ธฐ์ค์ ๊ธฐ๋ฅ ์์ฑ */
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.nine-hook-core {
|
|
72
|
+
width: 100%;
|
|
73
|
+
height: 100%;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/* ๐ฏ [ํต์ฌ ๋ณ๊ฒฝ 2] ๋ฆฌ์กํธ ์ฌ๋กฏ์ ๊ฐ๋ฆฌ์ง ์๊ณ , ์ค์ง "์ด ์ปดํฌ๋ํธ ๊ตฌ์ญ"๋ง ๊ฐ๋ ์ฑ์ฐ๋ ๋
๋ฆฝ ํ์
๋ ์ด์ด */
|
|
77
|
+
.nine-hook-inner-cover {
|
|
78
|
+
position: absolute !important;
|
|
79
|
+
top: 0 !important;
|
|
80
|
+
left: 0 !important;
|
|
81
|
+
width: 100% !important;
|
|
82
|
+
height: 100% !important;
|
|
83
|
+
box-sizing: border-box !important;
|
|
84
|
+
background-color: #FFF5F5 !important;
|
|
85
|
+
z-index: 2147483647 !important; /* ๋ฆฌ์กํธ ๋ด๋ถ ๊ทธ ์ด๋ค ์ค๋ฒ๋ ์ด๋ณด๋ค ๋ฌด์กฐ๊ฑด ์ */
|
|
86
|
+
overflow: auto !important;
|
|
87
|
+
display: none; /* ํ์์ ์จ๊น */
|
|
82
88
|
}
|
|
83
89
|
</style>
|
|
84
|
-
|
|
90
|
+
|
|
91
|
+
<div class="nine-hook-core">
|
|
85
92
|
<slot></slot>
|
|
86
93
|
</div>
|
|
87
|
-
<div class="nine-exception-board"></div>
|
|
94
|
+
<div class="nine-exception-board class-target-board"></div>
|
|
88
95
|
`;
|
|
89
96
|
}
|
|
90
97
|
|
|
@@ -98,8 +105,6 @@ export class ExceptionHook extends HTMLElement {
|
|
|
98
105
|
}
|
|
99
106
|
|
|
100
107
|
#handleRuntimeError = (event) => {
|
|
101
|
-
trace.log("๐จ [nine-exception-hook] window.addEventListener('error') ๋ฆฌ์ค๋ ํฌ์ฐฉ!!", event);
|
|
102
|
-
|
|
103
108
|
if (this.#hasError) return;
|
|
104
109
|
|
|
105
110
|
const errorMessage = event.error?.message || event.message || String(event);
|
|
@@ -111,8 +116,6 @@ export class ExceptionHook extends HTMLElement {
|
|
|
111
116
|
}
|
|
112
117
|
|
|
113
118
|
#handlePromiseError = (event) => {
|
|
114
|
-
trace.log("๐จ [nine-exception-hook] unhandledrejection (Promise ์๋ฌ) ํฌ์ฐฉ!!", event);
|
|
115
|
-
|
|
116
119
|
if (this.#hasError) return;
|
|
117
120
|
|
|
118
121
|
const reason = event.reason;
|
|
@@ -125,28 +128,21 @@ export class ExceptionHook extends HTMLElement {
|
|
|
125
128
|
#handleLocationChange = () => {
|
|
126
129
|
setTimeout(() => {
|
|
127
130
|
if (this.#hasError && this.#lastPath !== window.location.pathname) {
|
|
128
|
-
trace.log("โจ [nine-exception-hook] Shadow DOM ๋ฐ ๊ธ๋ก๋ฒ ์ค๋ฒ๋ ์ด ๋ด๋ถ ์์ธ ์ฒญ์ ๋ฐ ์ ์ ๋ณต๊ตฌ");
|
|
129
131
|
this.#lastPath = window.location.pathname;
|
|
130
132
|
this.#hasError = false;
|
|
131
133
|
|
|
132
|
-
this
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
134
|
+
const exceptionBoard = this.shadowRoot.querySelector('.nine-exception-board');
|
|
135
|
+
if (exceptionBoard) {
|
|
136
|
+
exceptionBoard.innerHTML = '';
|
|
137
|
+
exceptionBoard.className = 'nine-exception-board'; // ํด๋์ค ๋ฆฌ์
|
|
138
|
+
}
|
|
136
139
|
}
|
|
137
140
|
}, 50);
|
|
138
141
|
}
|
|
139
142
|
|
|
140
|
-
#removeExternalOverlay() {
|
|
141
|
-
const target = document.getElementById('nine-global-exception-container');
|
|
142
|
-
if (target) target.remove();
|
|
143
|
-
}
|
|
144
|
-
|
|
145
143
|
#sendToAiAction = async (errorMessage, errorStack) => {
|
|
146
|
-
|
|
147
|
-
const
|
|
148
|
-
const btn = root.querySelector('.nine-ai-btn');
|
|
149
|
-
const footer = root.querySelector('.nine-error-footer');
|
|
144
|
+
const btn = this.shadowRoot.querySelector('.nine-ai-btn');
|
|
145
|
+
const footer = this.shadowRoot.querySelector('.nine-error-footer');
|
|
150
146
|
if (!btn) return;
|
|
151
147
|
|
|
152
148
|
btn.disabled = true;
|
|
@@ -167,7 +163,6 @@ export class ExceptionHook extends HTMLElement {
|
|
|
167
163
|
throw new Error("window.triggerAutoRecovery ๊ด์ ํ ์์ง์ด ๋ก๋๋์ง ์์์ต๋๋ค.");
|
|
168
164
|
}
|
|
169
165
|
} catch (err) {
|
|
170
|
-
trace.error("โ AI ์ ์ก ์คํจ:", err);
|
|
171
166
|
btn.disabled = false;
|
|
172
167
|
btn.innerText = "โ ์ฌ์ ์ก ์๋";
|
|
173
168
|
footer.innerHTML = `<span style="color: #E53E3E;">โ ๏ธ ์ ์ก ์คํจ: ${err.message}</span>`;
|
|
@@ -179,55 +174,33 @@ export class ExceptionHook extends HTMLElement {
|
|
|
179
174
|
this.#hasError = true;
|
|
180
175
|
|
|
181
176
|
setTimeout(() => {
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
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
|
-
});
|
|
177
|
+
const exceptionBoard = this.shadowRoot.querySelector('.nine-exception-board');
|
|
178
|
+
if (!exceptionBoard) return;
|
|
179
|
+
|
|
180
|
+
// ๐ฏ [ํต์ฌ ๋ณ๊ฒฝ 3] ๊ธฐ์กด ์ฌ๋กฏ ์ปจํ
์ด๋๋ฅผ ์จ๊ธฐ์ง(display: none) ์์ต๋๋ค!
|
|
181
|
+
// ๋์ ์๋ฌ ๋ณด๋์ ์ปค๋ฒ ํด๋์ค๋ฅผ ์ฃผ์
ํ์ฌ "์ค์ง ๋ณธ๋ฌธ ๊ณต๊ฐ๋ง" ๋ฌผ๋ฆฌ์ ์ผ๋ก ์์ ํ ๋ฎ์ด์์๋๋ค.
|
|
182
|
+
exceptionBoard.className = 'nine-hook-inner-cover';
|
|
207
183
|
|
|
208
184
|
const errorHTML = `
|
|
209
|
-
<div class="nine-error-container" style="padding:
|
|
210
|
-
<h3 class="nine-error-title" style="color: #C53030; margin-top: 0; font-size:
|
|
211
|
-
<p class="nine-error-label" style="font-weight: bold; margin:
|
|
212
|
-
<pre class="nine-error-log" style="background: #1A202C; color: #EDF2F7; padding:
|
|
185
|
+
<div class="nine-error-container" style="padding: 30px; box-sizing: border-box; font-family: sans-serif; background: white; min-height: 100%; text-align: left;">
|
|
186
|
+
<h3 class="nine-error-title" style="color: #C53030; margin-top: 0; font-size: 20px; font-weight: 700; border-bottom: 2px solid #FED2D2; padding-bottom: 12px; font-family: sans-serif;">โ ๏ธ ์์คํ
์์ธ ๊ฐ์ง (${this.tagName.toLowerCase()})</h3>
|
|
187
|
+
<p class="nine-error-label" style="font-weight: bold; margin: 15px 0 6px 0; color: #4A5568; font-size: 14px; font-family: sans-serif;">[์๋ฌ ์์ธ ๋ก๊ทธ]:</p>
|
|
188
|
+
<pre class="nine-error-log" style="background: #1A202C; color: #EDF2F7; padding: 15px; border-radius: 6px; overflow-x: auto; white-space: pre-wrap; font-family: monospace; font-size: 13px; line-height: 1.5; margin-bottom: 20px;">${errorMessage}\n\n[Stack Trace]\n${errorStack}</pre>
|
|
213
189
|
|
|
214
|
-
<div class="nine-action-area" style="display: flex; align-items: center; gap:
|
|
215
|
-
<button class="nine-ai-btn" style="background: #3182CE; color: white; border: none; padding:
|
|
216
|
-
<div class="nine-error-footer" style="font-size:
|
|
190
|
+
<div class="nine-action-area" style="display: flex; align-items: center; gap: 15px; border-top: 1px solid #E2E8F0; padding-top: 15px;">
|
|
191
|
+
<button class="nine-ai-btn" style="background: #3182CE; color: white; border: none; padding: 10px 20px; border-radius: 6px; font-weight: bold; cursor: pointer; font-size: 14px;">๐ค AI์๊ฒ ์์ค์ฝ๋ ์์ ์์ฒญ</button>
|
|
192
|
+
<div class="nine-error-footer" style="font-size: 13px; color: #718096; line-height: 1.4; font-family: sans-serif;">
|
|
217
193
|
๋ฒํผ์ ๋๋ฅด๋ฉด AI๊ฐ ๋ก๊ทธ ๋ฐ ์ปดํฌ๋ํธ ๋งต์ ์ญ์ถ์ ํ์ฌ ์์ ์ ์์ํฉ๋๋ค.
|
|
218
194
|
</div>
|
|
219
195
|
</div>
|
|
220
196
|
</div>
|
|
221
197
|
`;
|
|
222
198
|
|
|
223
|
-
|
|
224
|
-
document.body.appendChild(externalContainer);
|
|
225
|
-
trace.log("๐จ [nine-exception-hook] ๋ธ๋ผ์ฐ์ Body ์ต์๋จ ๋ ์ด์ด ๋ฐฐ์ ์ฑ๊ณต");
|
|
199
|
+
exceptionBoard.innerHTML = errorHTML;
|
|
226
200
|
|
|
227
|
-
const aiBtn =
|
|
201
|
+
const aiBtn = exceptionBoard.querySelector('.nine-ai-btn');
|
|
228
202
|
if (aiBtn) {
|
|
229
203
|
aiBtn.addEventListener('click', () => this.#sendToAiAction(errorMessage, errorStack));
|
|
230
|
-
trace.log("๐จ [nine-exception-hook] AI ์์ฒญ ๋ฒํผ ์ด๋ฒคํธ ๋ฆฌ์ค๋ ์ต์ข
๋ฐ์ธ๋ฉ ์ฑ๊ณต");
|
|
231
204
|
}
|
|
232
205
|
}, 0);
|
|
233
206
|
}
|