@simplysm/angular 14.2.3 → 14.2.4
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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provideSdAngular.d.ts","sourceRoot":"","sources":["../../src/core/provideSdAngular.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"provideSdAngular.d.ts","sourceRoot":"","sources":["../../src/core/provideSdAngular.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAoE1D,wBAAgB,gBAAgB,CAAC,GAAG,EAAE;IAAE,UAAU,EAAE,MAAM,CAAA;CAAE,GAAG,oBAAoB,CA8KlF"}
|
|
@@ -14,6 +14,34 @@ import { SdOptionEventPlugin } from "./events/sd-option-event.plugin";
|
|
|
14
14
|
import { createLogger } from "@simplysm/core-common";
|
|
15
15
|
const logger = createLogger("angular:sw-update");
|
|
16
16
|
const themeLogger = createLogger("angular:theme");
|
|
17
|
+
const errorLogger = createLogger("angular:global-error");
|
|
18
|
+
// 브라우저 확장은 자기 스크립트를 페이지 main world 에 주입해 실행하므로,
|
|
19
|
+
// 확장이 던진 오류도 페이지의 전역 error/unhandledrejection 이벤트로 올라온다.
|
|
20
|
+
// 앱 결함이 아니므로 오버레이, 앱 종료 대상에서 제외한다.
|
|
21
|
+
const EXTENSION_URL_SCHEMES = [
|
|
22
|
+
"chrome-extension://",
|
|
23
|
+
"moz-extension://",
|
|
24
|
+
"safari-web-extension://",
|
|
25
|
+
];
|
|
26
|
+
// URL 스킴은 표준상 대소문자를 구분하지 않는다(RFC 3986 §3.1).
|
|
27
|
+
function isExtensionUrl(url) {
|
|
28
|
+
const lowerUrl = url.toLowerCase();
|
|
29
|
+
return EXTENSION_URL_SCHEMES.some((scheme) => lowerUrl.startsWith(scheme));
|
|
30
|
+
}
|
|
31
|
+
// 스택 포맷은 엔진마다 다르다(V8 은 "at fn (URL)", SpiderMonkey, JSC 는 "fn@URL").
|
|
32
|
+
// 포맷 대신 URL 이 처음 등장하는 줄을 최상단 프레임으로 보고, 그 URL 의 출처만 따진다.
|
|
33
|
+
// V8 의 "Error: 메시지" 헤더는 대개 URL 이 없어 건너뛰지만, 메시지에 URL 이 박히면 헤더가 최상단으로 잡힌다.
|
|
34
|
+
function isExtensionOriginRejection(reason) {
|
|
35
|
+
if (reason.stack == null)
|
|
36
|
+
return false;
|
|
37
|
+
for (const line of reason.stack.split("\n")) {
|
|
38
|
+
const topFrameUrl = /[a-z][a-z\d+.-]*:\/\/\S*/i.exec(line)?.[0];
|
|
39
|
+
if (topFrameUrl == null)
|
|
40
|
+
continue;
|
|
41
|
+
return isExtensionUrl(topFrameUrl);
|
|
42
|
+
}
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
17
45
|
export function provideSdAngular(opt) {
|
|
18
46
|
return makeEnvironmentProviders([
|
|
19
47
|
{
|
|
@@ -73,11 +101,19 @@ export function provideSdAngular(opt) {
|
|
|
73
101
|
const envInjector = inject(EnvironmentInjector);
|
|
74
102
|
const rejectionListener = (event) => {
|
|
75
103
|
event.preventDefault();
|
|
104
|
+
if (event.reason instanceof Error && isExtensionOriginRejection(event.reason)) {
|
|
105
|
+
errorLogger.warn("브라우저 확장 프로그램에서 발생한 오류로 판단해 무시함", event.reason);
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
76
108
|
const errorHandler = envInjector.get(ErrorHandler);
|
|
77
109
|
errorHandler.handleError(event);
|
|
78
110
|
};
|
|
79
111
|
const errorListener = (event) => {
|
|
80
112
|
event.preventDefault();
|
|
113
|
+
if (isExtensionUrl(event.filename)) {
|
|
114
|
+
errorLogger.warn("브라우저 확장 프로그램에서 발생한 오류로 판단해 무시함", `${event.message}\n${event.filename}(${event.lineno}, ${event.colno})`, event.error);
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
81
117
|
const errorHandler = envInjector.get(ErrorHandler);
|
|
82
118
|
errorHandler.handleError(event);
|
|
83
119
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@simplysm/angular",
|
|
3
|
-
"version": "14.2.
|
|
3
|
+
"version": "14.2.4",
|
|
4
4
|
"description": "심플리즘 패키지 - Angular",
|
|
5
5
|
"author": "심플리즘",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -58,10 +58,10 @@
|
|
|
58
58
|
"jspdf": "^4.2.1",
|
|
59
59
|
"rxjs": "^7.8.2",
|
|
60
60
|
"tabbable": "^6.5.0",
|
|
61
|
-
"@simplysm/core-browser": "14.2.
|
|
62
|
-
"@simplysm/
|
|
63
|
-
"@simplysm/service-
|
|
64
|
-
"@simplysm/
|
|
61
|
+
"@simplysm/core-browser": "14.2.4",
|
|
62
|
+
"@simplysm/core-common": "14.2.4",
|
|
63
|
+
"@simplysm/service-common": "14.2.4",
|
|
64
|
+
"@simplysm/service-client": "14.2.4"
|
|
65
65
|
},
|
|
66
66
|
"devDependencies": {
|
|
67
67
|
"@angular/compiler": "^22.0.7"
|
|
@@ -33,6 +33,38 @@ import { createLogger } from "@simplysm/core-common";
|
|
|
33
33
|
|
|
34
34
|
const logger = createLogger("angular:sw-update");
|
|
35
35
|
const themeLogger = createLogger("angular:theme");
|
|
36
|
+
const errorLogger = createLogger("angular:global-error");
|
|
37
|
+
|
|
38
|
+
// 브라우저 확장은 자기 스크립트를 페이지 main world 에 주입해 실행하므로,
|
|
39
|
+
// 확장이 던진 오류도 페이지의 전역 error/unhandledrejection 이벤트로 올라온다.
|
|
40
|
+
// 앱 결함이 아니므로 오버레이, 앱 종료 대상에서 제외한다.
|
|
41
|
+
const EXTENSION_URL_SCHEMES = [
|
|
42
|
+
"chrome-extension://",
|
|
43
|
+
"moz-extension://",
|
|
44
|
+
"safari-web-extension://",
|
|
45
|
+
];
|
|
46
|
+
|
|
47
|
+
// URL 스킴은 표준상 대소문자를 구분하지 않는다(RFC 3986 §3.1).
|
|
48
|
+
function isExtensionUrl(url: string): boolean {
|
|
49
|
+
const lowerUrl = url.toLowerCase();
|
|
50
|
+
return EXTENSION_URL_SCHEMES.some((scheme) => lowerUrl.startsWith(scheme));
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// 스택 포맷은 엔진마다 다르다(V8 은 "at fn (URL)", SpiderMonkey, JSC 는 "fn@URL").
|
|
54
|
+
// 포맷 대신 URL 이 처음 등장하는 줄을 최상단 프레임으로 보고, 그 URL 의 출처만 따진다.
|
|
55
|
+
// V8 의 "Error: 메시지" 헤더는 대개 URL 이 없어 건너뛰지만, 메시지에 URL 이 박히면 헤더가 최상단으로 잡힌다.
|
|
56
|
+
function isExtensionOriginRejection(reason: Error): boolean {
|
|
57
|
+
if (reason.stack == null) return false;
|
|
58
|
+
|
|
59
|
+
for (const line of reason.stack.split("\n")) {
|
|
60
|
+
const topFrameUrl = /[a-z][a-z\d+.-]*:\/\/\S*/i.exec(line)?.[0];
|
|
61
|
+
if (topFrameUrl == null) continue;
|
|
62
|
+
|
|
63
|
+
return isExtensionUrl(topFrameUrl);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
36
68
|
|
|
37
69
|
export function provideSdAngular(opt: { clientName: string }): EnvironmentProviders {
|
|
38
70
|
return makeEnvironmentProviders([
|
|
@@ -99,12 +131,28 @@ export function provideSdAngular(opt: { clientName: string }): EnvironmentProvid
|
|
|
99
131
|
|
|
100
132
|
const rejectionListener = (event: PromiseRejectionEvent) => {
|
|
101
133
|
event.preventDefault();
|
|
134
|
+
|
|
135
|
+
if (event.reason instanceof Error && isExtensionOriginRejection(event.reason)) {
|
|
136
|
+
errorLogger.warn("브라우저 확장 프로그램에서 발생한 오류로 판단해 무시함", event.reason);
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
|
|
102
140
|
const errorHandler = envInjector.get(ErrorHandler);
|
|
103
141
|
errorHandler.handleError(event);
|
|
104
142
|
};
|
|
105
143
|
|
|
106
144
|
const errorListener = (event: ErrorEvent) => {
|
|
107
145
|
event.preventDefault();
|
|
146
|
+
|
|
147
|
+
if (isExtensionUrl(event.filename)) {
|
|
148
|
+
errorLogger.warn(
|
|
149
|
+
"브라우저 확장 프로그램에서 발생한 오류로 판단해 무시함",
|
|
150
|
+
`${event.message}\n${event.filename}(${event.lineno}, ${event.colno})`,
|
|
151
|
+
event.error,
|
|
152
|
+
);
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
|
|
108
156
|
const errorHandler = envInjector.get(ErrorHandler);
|
|
109
157
|
errorHandler.handleError(event);
|
|
110
158
|
};
|