@nebulaaa/sentry 0.0.0-stage → 1.0.0

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.
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "@nebulaaa/sentry",
3
+ "version": "1.0.0",
4
+ "description": "哨兵(异常监控)插件",
5
+ "author": "doooreyn",
6
+ "license": "MIT",
7
+ "keywords": [
8
+ "sentry",
9
+ "nebulaaa"
10
+ ],
11
+ "engines": {
12
+ "node": ">=16.0.0",
13
+ "npm": ">=10.0.0"
14
+ },
15
+ "main": "./sentry.cjs",
16
+ "module": "./sentry.mjs",
17
+ "types": "./sentry.d.ts",
18
+ "exports": {
19
+ ".": {
20
+ "types": "./sentry.d.ts",
21
+ "require": "./sentry.cjs",
22
+ "import": "./sentry.mjs",
23
+ "default": "./sentry.cjs"
24
+ },
25
+ "./min": {
26
+ "require": "./sentry.min.cjs",
27
+ "import": "./sentry.min.mjs"
28
+ }
29
+ },
30
+ "publishConfig": {
31
+ "registry": "https://registry.npmjs.org/",
32
+ "access": "public"
33
+ }
34
+ }
@@ -0,0 +1,201 @@
1
+ 'use strict';
2
+
3
+ var cc = require('cc');
4
+ var ms = require('@nebulaaa/ms');
5
+ var plugin = require('@nebulaaa/plugin');
6
+ var reporter = require('@nebulaaa/reporter');
7
+
8
+ /**
9
+ * 异常类型
10
+ */
11
+ exports.SentryType = void 0;
12
+ (function (SentryType) {
13
+ /** JavaScript 错误 */
14
+ SentryType["JAVASCRIPT"] = "JAVASCRIPT";
15
+ /** Promise 拒绝 */
16
+ SentryType["PROMISE"] = "PROMISE";
17
+ /** 原生错误 */
18
+ SentryType["NATIVE"] = "NATIVE";
19
+ })(exports.SentryType || (exports.SentryType = {}));
20
+
21
+ /**
22
+ * 哨兵能力实现
23
+ *
24
+ * 职责:
25
+ * - 捕获全局 JavaScript 错误
26
+ * - 捕获未处理的 Promise 拒绝
27
+ * - 通知上报中心报告异常
28
+ */
29
+ class SentryPlugin extends plugin.Plugin {
30
+ constructor(deps, cfg) {
31
+ super(deps, cfg);
32
+ this._stats = {
33
+ Total: 0,
34
+ Javascript: 0,
35
+ Promise: 0,
36
+ Native: 0,
37
+ };
38
+ this._jsErrorHandler = null;
39
+ this._promiseRejectionHandler = null;
40
+ this._nativeErrorHandler = null;
41
+ const global = this.Deps.Access.Global;
42
+ if (global.Has('addEventListener')) {
43
+ const addEventListener = global.Get('addEventListener');
44
+ // 注册全局错误处理器和Promise 拒绝处理器
45
+ this._jsErrorHandler = this.handleJavaScriptError.bind(this);
46
+ this._promiseRejectionHandler = this.handlePromiseRejection.bind(this);
47
+ addEventListener('error', this._jsErrorHandler);
48
+ addEventListener('unhandledrejection', this._promiseRejectionHandler);
49
+ }
50
+ if (cc.sys.isNative) {
51
+ // 注册原生错误处理器
52
+ this._nativeErrorHandler = global.Get('__errorHandler');
53
+ global.Set('__errorHandler', this.handleNativeError.bind(this));
54
+ }
55
+ }
56
+ /**
57
+ * 处理 JavaScript 错误
58
+ */
59
+ handleJavaScriptError(event) {
60
+ var _a;
61
+ this._stats.Total++;
62
+ this._stats.Javascript++;
63
+ const error = {
64
+ Type: exports.SentryType.JAVASCRIPT,
65
+ Code: 'JAVASCRIPT_ERROR',
66
+ Message: event.message || 'Unknown error',
67
+ Timestamp: ms.Now(),
68
+ Stack: (_a = event.error) === null || _a === void 0 ? void 0 : _a.stack,
69
+ Filename: event.filename,
70
+ Lineno: event.lineno,
71
+ Colno: event.colno,
72
+ };
73
+ this.sendToReporter(error);
74
+ }
75
+ /**
76
+ * 处理 Promise 拒绝
77
+ */
78
+ handlePromiseRejection(event) {
79
+ this._stats.Total++;
80
+ this._stats.Promise++;
81
+ const { reason } = event;
82
+ let message;
83
+ let stack;
84
+ if (reason instanceof Error) {
85
+ const { message: _message, stack: _stack } = reason;
86
+ message = _message;
87
+ stack = _stack;
88
+ }
89
+ else if (typeof reason === 'string') {
90
+ message = reason;
91
+ }
92
+ else {
93
+ message = this.stringifyReason(reason);
94
+ stack = this.extractStack(reason);
95
+ }
96
+ const error = {
97
+ Type: exports.SentryType.PROMISE,
98
+ Code: 'PROMISE_REJECTION',
99
+ Message: message,
100
+ Timestamp: ms.Now(),
101
+ Stack: stack,
102
+ };
103
+ this.sendToReporter(error);
104
+ }
105
+ /**
106
+ * 安全序列化拒绝原因
107
+ *
108
+ * @tip String(reason) 可因 toPrimitive/toString 抛出异常(异常将从事件监听器逃逸,
109
+ * 造成计数与转发不一致);普通对象还会退化为无信息量的 '[object Object]'。
110
+ * 故逐级回退:message 属性 → String → JSON.stringify → Object.prototype.toString
111
+ */
112
+ stringifyReason(reason) {
113
+ // 跨 realm Error 实例 / 自带 message 的对象,优先提取 message
114
+ if (reason !== null && typeof reason === 'object') {
115
+ try {
116
+ const { message } = reason;
117
+ if (typeof message === 'string' && message.length > 0) {
118
+ return message;
119
+ }
120
+ }
121
+ catch (e) {
122
+ // message 读取器抛错,走后续回退
123
+ }
124
+ }
125
+ // String 可抛(toPrimitive/toString);结果为 '[object Object]' 时无信息量
126
+ try {
127
+ const text = String(reason);
128
+ if (text !== '[object Object]') {
129
+ return text;
130
+ }
131
+ }
132
+ catch (e) {
133
+ // 忽略,走后续回退
134
+ }
135
+ // JSON 可抛(循环引用 / toJSON 抛错)
136
+ try {
137
+ const json = JSON.stringify(reason);
138
+ if (typeof json === 'string') {
139
+ return json;
140
+ }
141
+ }
142
+ catch (e) {
143
+ // 忽略,走末级回退
144
+ }
145
+ return Object.prototype.toString.call(reason);
146
+ }
147
+ /**
148
+ * 提取 Error 形态对象的堆栈
149
+ * @tip 跨 realm Error 实例不是 instanceof Error,其 message/stack 属性原样可取
150
+ */
151
+ extractStack(reason) {
152
+ if (reason !== null && typeof reason === 'object') {
153
+ try {
154
+ const { stack } = reason;
155
+ if (typeof stack === 'string') {
156
+ return stack;
157
+ }
158
+ }
159
+ catch (e) {
160
+ // stack 读取器抛错,保持 undefined
161
+ }
162
+ }
163
+ return undefined;
164
+ }
165
+ /**
166
+ * 处理原生错误
167
+ */
168
+ /**
169
+ * 处理原生错误
170
+ */
171
+ handleNativeError(name, line, msg, stack) {
172
+ var _a;
173
+ this._stats.Total++;
174
+ this._stats.Native++;
175
+ (_a = this._nativeErrorHandler) === null || _a === void 0 ? void 0 : _a.call(this, name, line, msg, stack);
176
+ const error = {
177
+ Type: exports.SentryType.NATIVE,
178
+ Code: 'NATIVE_ERROR',
179
+ Message: msg,
180
+ Filename: name,
181
+ Lineno: line,
182
+ Timestamp: ms.Now(),
183
+ Stack: stack,
184
+ };
185
+ this.sendToReporter(error);
186
+ }
187
+ /**
188
+ * 报告给记者
189
+ */
190
+ sendToReporter(error) {
191
+ this.Logger.Error('捕获到异常', error);
192
+ if (this.Deps.Launcher.IsDev)
193
+ return;
194
+ this.Deps.Reporter.Collect(reporter.ReporterType.ERROR, error.Code, error.Message, Object.assign({}, error));
195
+ }
196
+ get Stats() {
197
+ return Object.assign({}, this._stats);
198
+ }
199
+ }
200
+
201
+ exports.SentryPlugin = SentryPlugin;
@@ -0,0 +1,121 @@
1
+ import { IAccessPlugin } from '@nebulaaa/access';
2
+ import { ILauncherPlugin } from '@nebulaaa/launcher';
3
+ import { IPlugin, PluginDeps, PluginCfg, Plugin } from '@nebulaaa/plugin';
4
+ import { IReporterPlugin } from '@nebulaaa/reporter';
5
+
6
+ /**
7
+ * 异常类型
8
+ */
9
+ declare enum SentryType {
10
+ /** JavaScript 错误 */
11
+ JAVASCRIPT = "JAVASCRIPT",
12
+ /** Promise 拒绝 */
13
+ PROMISE = "PROMISE",
14
+ /** 原生错误 */
15
+ NATIVE = "NATIVE"
16
+ }
17
+ /**
18
+ * 异常数据
19
+ */
20
+ interface SentryPayload {
21
+ /** 异常类型 */
22
+ Type: SentryType;
23
+ /** 异常代码 */
24
+ Code: string;
25
+ /** 异常消息 */
26
+ Message: string;
27
+ /** 异常时间戳 */
28
+ Timestamp: number;
29
+ /** 异常堆栈 */
30
+ Stack?: string;
31
+ /** 额外数据 */
32
+ Data?: Record<string, unknown>;
33
+ /** 文件名 */
34
+ Filename?: string;
35
+ /** 行号 */
36
+ Lineno?: number;
37
+ /** 列号 */
38
+ Colno?: number;
39
+ }
40
+ /**
41
+ * 哨兵统计
42
+ */
43
+ interface SentryStats {
44
+ /** 捕获的错误总数 */
45
+ Total: number;
46
+ /** 捕获的 JavaScript 错误总数 */
47
+ Javascript: number;
48
+ /** 捕获的 Promise 拒绝总数 */
49
+ Promise: number;
50
+ /** 捕获的原生错误总数 */
51
+ Native: number;
52
+ }
53
+ /** 哨兵插件依赖 */
54
+ interface SentryDeps extends PluginDeps {
55
+ Access: IAccessPlugin;
56
+ Reporter: IReporterPlugin;
57
+ Launcher: ILauncherPlugin;
58
+ }
59
+ /** 哨兵插件配置 */
60
+ interface SentryCfg extends PluginCfg {
61
+ }
62
+ /** 哨兵插件接口 */
63
+ interface ISentryPlugin extends IPlugin<SentryDeps, SentryCfg> {
64
+ get Stats(): SentryStats;
65
+ }
66
+
67
+ /**
68
+ * 哨兵能力实现
69
+ *
70
+ * 职责:
71
+ * - 捕获全局 JavaScript 错误
72
+ * - 捕获未处理的 Promise 拒绝
73
+ * - 通知上报中心报告异常
74
+ */
75
+ declare class SentryPlugin extends Plugin<SentryDeps, SentryCfg> implements ISentryPlugin {
76
+ /** 统计 */
77
+ private _stats;
78
+ /** JavaScript 错误处理器 */
79
+ private _jsErrorHandler;
80
+ /** Promise 拒绝处理器 */
81
+ private _promiseRejectionHandler;
82
+ /** 原生错误捕获 */
83
+ private _nativeErrorHandler;
84
+ constructor(deps: SentryDeps, cfg: SentryCfg);
85
+ /**
86
+ * 处理 JavaScript 错误
87
+ */
88
+ private handleJavaScriptError;
89
+ /**
90
+ * 处理 Promise 拒绝
91
+ */
92
+ private handlePromiseRejection;
93
+ /**
94
+ * 安全序列化拒绝原因
95
+ *
96
+ * @tip String(reason) 可因 toPrimitive/toString 抛出异常(异常将从事件监听器逃逸,
97
+ * 造成计数与转发不一致);普通对象还会退化为无信息量的 '[object Object]'。
98
+ * 故逐级回退:message 属性 → String → JSON.stringify → Object.prototype.toString
99
+ */
100
+ private stringifyReason;
101
+ /**
102
+ * 提取 Error 形态对象的堆栈
103
+ * @tip 跨 realm Error 实例不是 instanceof Error,其 message/stack 属性原样可取
104
+ */
105
+ private extractStack;
106
+ /**
107
+ * 处理原生错误
108
+ */
109
+ /**
110
+ * 处理原生错误
111
+ */
112
+ private handleNativeError;
113
+ /**
114
+ * 报告给记者
115
+ */
116
+ private sendToReporter;
117
+ get Stats(): SentryStats;
118
+ }
119
+
120
+ export { SentryPlugin, SentryType };
121
+ export type { ISentryPlugin, SentryCfg, SentryDeps, SentryPayload, SentryStats };
@@ -0,0 +1 @@
1
+ "use strict";var e,t=require("cc"),r=require("@nebulaaa/ms"),s=require("@nebulaaa/plugin"),n=require("@nebulaaa/reporter");exports.SentryType=void 0,(e=exports.SentryType||(exports.SentryType={})).JAVASCRIPT="JAVASCRIPT",e.PROMISE="PROMISE",e.NATIVE="NATIVE";class i extends s.Plugin{constructor(e,r){super(e,r),this._stats={Total:0,Javascript:0,Promise:0,Native:0},this._jsErrorHandler=null,this._promiseRejectionHandler=null,this._nativeErrorHandler=null;const s=this.Deps.Access.Global;if(s.Has("addEventListener")){const e=s.Get("addEventListener");this._jsErrorHandler=this.handleJavaScriptError.bind(this),this._promiseRejectionHandler=this.handlePromiseRejection.bind(this),e("error",this._jsErrorHandler),e("unhandledrejection",this._promiseRejectionHandler)}t.sys.isNative&&(this._nativeErrorHandler=s.Get("__errorHandler"),s.Set("__errorHandler",this.handleNativeError.bind(this)))}handleJavaScriptError(e){var t;this._stats.Total++,this._stats.Javascript++;const s={Type:exports.SentryType.JAVASCRIPT,Code:"JAVASCRIPT_ERROR",Message:e.message||"Unknown error",Timestamp:r.Now(),Stack:null===(t=e.error)||void 0===t?void 0:t.stack,Filename:e.filename,Lineno:e.lineno,Colno:e.colno};this.sendToReporter(s)}handlePromiseRejection(e){this._stats.Total++,this._stats.Promise++;const{reason:t}=e;let s,n;if(t instanceof Error){const{message:e,stack:r}=t;s=e,n=r}else"string"==typeof t?s=t:(s=this.stringifyReason(t),n=this.extractStack(t));const i={Type:exports.SentryType.PROMISE,Code:"PROMISE_REJECTION",Message:s,Timestamp:r.Now(),Stack:n};this.sendToReporter(i)}stringifyReason(e){if(null!==e&&"object"==typeof e)try{const{message:t}=e;if("string"==typeof t&&t.length>0)return t}catch(e){}try{const t=String(e);if("[object Object]"!==t)return t}catch(e){}try{const t=JSON.stringify(e);if("string"==typeof t)return t}catch(e){}return Object.prototype.toString.call(e)}extractStack(e){if(null!==e&&"object"==typeof e)try{const{stack:t}=e;if("string"==typeof t)return t}catch(e){}}handleNativeError(e,t,s,n){var i;this._stats.Total++,this._stats.Native++,null===(i=this._nativeErrorHandler)||void 0===i||i.call(this,e,t,s,n);const o={Type:exports.SentryType.NATIVE,Code:"NATIVE_ERROR",Message:s,Filename:e,Lineno:t,Timestamp:r.Now(),Stack:n};this.sendToReporter(o)}sendToReporter(e){this.Logger.Error("捕获到异常",e),this.Deps.Launcher.IsDev||this.Deps.Reporter.Collect(n.ReporterType.ERROR,e.Code,e.Message,Object.assign({},e))}get Stats(){return Object.assign({},this._stats)}}exports.SentryPlugin=i;
@@ -0,0 +1 @@
1
+ import{sys as t}from"cc";import{Now as e}from"@nebulaaa/ms";import{Plugin as r}from"@nebulaaa/plugin";import{ReporterType as s}from"@nebulaaa/reporter";var i;!function(t){t.JAVASCRIPT="JAVASCRIPT",t.PROMISE="PROMISE",t.NATIVE="NATIVE"}(i||(i={}));class n extends r{constructor(e,r){super(e,r),this._stats={Total:0,Javascript:0,Promise:0,Native:0},this._jsErrorHandler=null,this._promiseRejectionHandler=null,this._nativeErrorHandler=null;const s=this.Deps.Access.Global;if(s.Has("addEventListener")){const t=s.Get("addEventListener");this._jsErrorHandler=this.handleJavaScriptError.bind(this),this._promiseRejectionHandler=this.handlePromiseRejection.bind(this),t("error",this._jsErrorHandler),t("unhandledrejection",this._promiseRejectionHandler)}t.isNative&&(this._nativeErrorHandler=s.Get("__errorHandler"),s.Set("__errorHandler",this.handleNativeError.bind(this)))}handleJavaScriptError(t){var r;this._stats.Total++,this._stats.Javascript++;const s={Type:i.JAVASCRIPT,Code:"JAVASCRIPT_ERROR",Message:t.message||"Unknown error",Timestamp:e(),Stack:null===(r=t.error)||void 0===r?void 0:r.stack,Filename:t.filename,Lineno:t.lineno,Colno:t.colno};this.sendToReporter(s)}handlePromiseRejection(t){this._stats.Total++,this._stats.Promise++;const{reason:r}=t;let s,n;if(r instanceof Error){const{message:t,stack:e}=r;s=t,n=e}else"string"==typeof r?s=r:(s=this.stringifyReason(r),n=this.extractStack(r));const o={Type:i.PROMISE,Code:"PROMISE_REJECTION",Message:s,Timestamp:e(),Stack:n};this.sendToReporter(o)}stringifyReason(t){if(null!==t&&"object"==typeof t)try{const{message:e}=t;if("string"==typeof e&&e.length>0)return e}catch(t){}try{const e=String(t);if("[object Object]"!==e)return e}catch(t){}try{const e=JSON.stringify(t);if("string"==typeof e)return e}catch(t){}return Object.prototype.toString.call(t)}extractStack(t){if(null!==t&&"object"==typeof t)try{const{stack:e}=t;if("string"==typeof e)return e}catch(t){}}handleNativeError(t,r,s,n){var o;this._stats.Total++,this._stats.Native++,null===(o=this._nativeErrorHandler)||void 0===o||o.call(this,t,r,s,n);const a={Type:i.NATIVE,Code:"NATIVE_ERROR",Message:s,Filename:t,Lineno:r,Timestamp:e(),Stack:n};this.sendToReporter(a)}sendToReporter(t){this.Logger.Error("捕获到异常",t),this.Deps.Launcher.IsDev||this.Deps.Reporter.Collect(s.ERROR,t.Code,t.Message,Object.assign({},t))}get Stats(){return Object.assign({},this._stats)}}export{n as SentryPlugin,i as SentryType};
@@ -0,0 +1,199 @@
1
+ import { sys } from 'cc';
2
+ import { Now } from '@nebulaaa/ms';
3
+ import { Plugin } from '@nebulaaa/plugin';
4
+ import { ReporterType } from '@nebulaaa/reporter';
5
+
6
+ /**
7
+ * 异常类型
8
+ */
9
+ var SentryType;
10
+ (function (SentryType) {
11
+ /** JavaScript 错误 */
12
+ SentryType["JAVASCRIPT"] = "JAVASCRIPT";
13
+ /** Promise 拒绝 */
14
+ SentryType["PROMISE"] = "PROMISE";
15
+ /** 原生错误 */
16
+ SentryType["NATIVE"] = "NATIVE";
17
+ })(SentryType || (SentryType = {}));
18
+
19
+ /**
20
+ * 哨兵能力实现
21
+ *
22
+ * 职责:
23
+ * - 捕获全局 JavaScript 错误
24
+ * - 捕获未处理的 Promise 拒绝
25
+ * - 通知上报中心报告异常
26
+ */
27
+ class SentryPlugin extends Plugin {
28
+ constructor(deps, cfg) {
29
+ super(deps, cfg);
30
+ this._stats = {
31
+ Total: 0,
32
+ Javascript: 0,
33
+ Promise: 0,
34
+ Native: 0,
35
+ };
36
+ this._jsErrorHandler = null;
37
+ this._promiseRejectionHandler = null;
38
+ this._nativeErrorHandler = null;
39
+ const global = this.Deps.Access.Global;
40
+ if (global.Has('addEventListener')) {
41
+ const addEventListener = global.Get('addEventListener');
42
+ // 注册全局错误处理器和Promise 拒绝处理器
43
+ this._jsErrorHandler = this.handleJavaScriptError.bind(this);
44
+ this._promiseRejectionHandler = this.handlePromiseRejection.bind(this);
45
+ addEventListener('error', this._jsErrorHandler);
46
+ addEventListener('unhandledrejection', this._promiseRejectionHandler);
47
+ }
48
+ if (sys.isNative) {
49
+ // 注册原生错误处理器
50
+ this._nativeErrorHandler = global.Get('__errorHandler');
51
+ global.Set('__errorHandler', this.handleNativeError.bind(this));
52
+ }
53
+ }
54
+ /**
55
+ * 处理 JavaScript 错误
56
+ */
57
+ handleJavaScriptError(event) {
58
+ var _a;
59
+ this._stats.Total++;
60
+ this._stats.Javascript++;
61
+ const error = {
62
+ Type: SentryType.JAVASCRIPT,
63
+ Code: 'JAVASCRIPT_ERROR',
64
+ Message: event.message || 'Unknown error',
65
+ Timestamp: Now(),
66
+ Stack: (_a = event.error) === null || _a === void 0 ? void 0 : _a.stack,
67
+ Filename: event.filename,
68
+ Lineno: event.lineno,
69
+ Colno: event.colno,
70
+ };
71
+ this.sendToReporter(error);
72
+ }
73
+ /**
74
+ * 处理 Promise 拒绝
75
+ */
76
+ handlePromiseRejection(event) {
77
+ this._stats.Total++;
78
+ this._stats.Promise++;
79
+ const { reason } = event;
80
+ let message;
81
+ let stack;
82
+ if (reason instanceof Error) {
83
+ const { message: _message, stack: _stack } = reason;
84
+ message = _message;
85
+ stack = _stack;
86
+ }
87
+ else if (typeof reason === 'string') {
88
+ message = reason;
89
+ }
90
+ else {
91
+ message = this.stringifyReason(reason);
92
+ stack = this.extractStack(reason);
93
+ }
94
+ const error = {
95
+ Type: SentryType.PROMISE,
96
+ Code: 'PROMISE_REJECTION',
97
+ Message: message,
98
+ Timestamp: Now(),
99
+ Stack: stack,
100
+ };
101
+ this.sendToReporter(error);
102
+ }
103
+ /**
104
+ * 安全序列化拒绝原因
105
+ *
106
+ * @tip String(reason) 可因 toPrimitive/toString 抛出异常(异常将从事件监听器逃逸,
107
+ * 造成计数与转发不一致);普通对象还会退化为无信息量的 '[object Object]'。
108
+ * 故逐级回退:message 属性 → String → JSON.stringify → Object.prototype.toString
109
+ */
110
+ stringifyReason(reason) {
111
+ // 跨 realm Error 实例 / 自带 message 的对象,优先提取 message
112
+ if (reason !== null && typeof reason === 'object') {
113
+ try {
114
+ const { message } = reason;
115
+ if (typeof message === 'string' && message.length > 0) {
116
+ return message;
117
+ }
118
+ }
119
+ catch (e) {
120
+ // message 读取器抛错,走后续回退
121
+ }
122
+ }
123
+ // String 可抛(toPrimitive/toString);结果为 '[object Object]' 时无信息量
124
+ try {
125
+ const text = String(reason);
126
+ if (text !== '[object Object]') {
127
+ return text;
128
+ }
129
+ }
130
+ catch (e) {
131
+ // 忽略,走后续回退
132
+ }
133
+ // JSON 可抛(循环引用 / toJSON 抛错)
134
+ try {
135
+ const json = JSON.stringify(reason);
136
+ if (typeof json === 'string') {
137
+ return json;
138
+ }
139
+ }
140
+ catch (e) {
141
+ // 忽略,走末级回退
142
+ }
143
+ return Object.prototype.toString.call(reason);
144
+ }
145
+ /**
146
+ * 提取 Error 形态对象的堆栈
147
+ * @tip 跨 realm Error 实例不是 instanceof Error,其 message/stack 属性原样可取
148
+ */
149
+ extractStack(reason) {
150
+ if (reason !== null && typeof reason === 'object') {
151
+ try {
152
+ const { stack } = reason;
153
+ if (typeof stack === 'string') {
154
+ return stack;
155
+ }
156
+ }
157
+ catch (e) {
158
+ // stack 读取器抛错,保持 undefined
159
+ }
160
+ }
161
+ return undefined;
162
+ }
163
+ /**
164
+ * 处理原生错误
165
+ */
166
+ /**
167
+ * 处理原生错误
168
+ */
169
+ handleNativeError(name, line, msg, stack) {
170
+ var _a;
171
+ this._stats.Total++;
172
+ this._stats.Native++;
173
+ (_a = this._nativeErrorHandler) === null || _a === void 0 ? void 0 : _a.call(this, name, line, msg, stack);
174
+ const error = {
175
+ Type: SentryType.NATIVE,
176
+ Code: 'NATIVE_ERROR',
177
+ Message: msg,
178
+ Filename: name,
179
+ Lineno: line,
180
+ Timestamp: Now(),
181
+ Stack: stack,
182
+ };
183
+ this.sendToReporter(error);
184
+ }
185
+ /**
186
+ * 报告给记者
187
+ */
188
+ sendToReporter(error) {
189
+ this.Logger.Error('捕获到异常', error);
190
+ if (this.Deps.Launcher.IsDev)
191
+ return;
192
+ this.Deps.Reporter.Collect(ReporterType.ERROR, error.Code, error.Message, Object.assign({}, error));
193
+ }
194
+ get Stats() {
195
+ return Object.assign({}, this._stats);
196
+ }
197
+ }
198
+
199
+ export { SentryPlugin, SentryType };
package/package.json CHANGED
@@ -1,6 +1,73 @@
1
- {
2
- "name": "@nebulaaa/sentry",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
1
+ {
2
+ "name": "@nebulaaa/sentry",
3
+ "version": "1.0.0",
4
+ "description": "哨兵(异常监控)插件",
5
+ "main": "./dist/sentry.cjs",
6
+ "module": "./dist/sentry.mjs",
7
+ "types": "./dist/sentry.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "require": "./dist/sentry.cjs",
11
+ "import": "./dist/sentry.mjs",
12
+ "types": "./dist/sentry.d.ts",
13
+ "default": "./dist/sentry.cjs"
14
+ },
15
+ "./min": {
16
+ "require": "./dist/sentry.min.cjs",
17
+ "import": "./dist/sentry.min.mjs"
18
+ }
19
+ },
20
+ "files": [
21
+ "dist"
22
+ ],
23
+ "scripts": {
24
+ "clean": "node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\"",
25
+ "build": "npm run clean && rollup -c rollup.config.mjs && node ../scripts/write-dist-package.mjs sentry",
26
+ "test": "jest"
27
+ },
28
+ "keywords": [
29
+ "sentry",
30
+ "nebulaaa"
31
+ ],
32
+ "author": "doooreyn",
33
+ "license": "MIT",
34
+ "devEngines": {
35
+ "packageManager": {
36
+ "name": "npm",
37
+ "version": ">=10.0.0",
38
+ "onFail": "warn"
39
+ }
40
+ },
41
+ "engines": {
42
+ "node": ">=16.0.0",
43
+ "npm": ">=10.0.0"
44
+ },
45
+ "publishConfig": {
46
+ "registry": "https://registry.npmjs.org/",
47
+ "access": "public"
48
+ },
49
+ "allowScripts": {
50
+ "unrs-resolver@1.12.2": true,
51
+ "@parcel/watcher@2.6.0": true
52
+ },
53
+ "devDependencies": {
54
+ "@cocos/creator-types": "^3.8.8",
55
+ "@rollup/plugin-terser": "^1.0.2",
56
+ "@rollup/plugin-typescript": "^12.1.2",
57
+ "@types/jest": "^30.0.0",
58
+ "@types/node": "^22.10.2",
59
+ "jest": "^30.5.2",
60
+ "rollup": "^4.28.1",
61
+ "rollup-plugin-dts": "^6.1.1",
62
+ "ts-jest": "^29.1.2",
63
+ "ts-node": "^10.9.2",
64
+ "typescript": "5.7.3"
65
+ },
66
+ "dependencies": {
67
+ "@nebulaaa/access": "^2.0.2",
68
+ "@nebulaaa/launcher": "^2.0.1",
69
+ "@nebulaaa/ms": "^1.1.0",
70
+ "@nebulaaa/plugin": "^1.0.0",
71
+ "@nebulaaa/reporter": "^1.0.2"
72
+ }
73
+ }
package/README.md DELETED
@@ -1,3 +0,0 @@
1
- # Temporary Holding Version
2
-
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.