1
1
import { addGlobalEventProcessor , getCurrentHub } from '@sentry/core' ;
2
- import { Event , EventHint , Integration , StackFrame } from '@sentry/types' ;
3
- import { logger } from '@sentry/utils' ;
2
+ import { Event , EventHint , Integration , StackFrame , StackLineParser } from '@sentry/types' ;
3
+ import { logger , stackParserFromStackParserOptions } from '@sentry/utils' ;
4
4
5
5
// const INTERNAL_CALLSITES_REGEX = new RegExp(['/Libraries/Renderer/oss/NativescriptRenderer-dev\\.js$', '/Libraries/BatchedBridge/MessageQueue\\.js$'].join('|'));
6
6
@@ -19,6 +19,7 @@ interface NativescriptFrame {
19
19
* React Native Error
20
20
*/
21
21
type NativescriptError = Error & {
22
+ stackTrace ?: string ;
22
23
framesToPop ?: number ;
23
24
jsEngine ?: string ;
24
25
preventSymbolication ?: boolean ;
@@ -32,44 +33,81 @@ type NativescriptError = Error & {
32
33
// isComponentError?: boolean,
33
34
// ...
34
35
// };
36
+ const UNKNOWN_FUNCTION = undefined ;
35
37
36
- export function parseErrorStack ( e : NativescriptError ) : NativescriptFrame [ ] {
37
- if ( ! e || ! e . stack ) {
38
- return [ ] ;
39
- }
40
- const stacktraceParser = require ( 'stacktrace-parser' ) ;
41
- if ( Array . isArray ( e . stack ) ) {
42
- return e . stack ;
43
- } else {
44
- return stacktraceParser . parse ( 'at ' + e . stack ) . map ( frame => ( {
45
- ...frame ,
46
- column : frame . column != null ? frame . column - 1 : null
47
- } ) ) ;
48
- }
38
+ export interface NativescriptStackFrame extends StackFrame {
39
+ native ?: boolean ;
49
40
}
50
41
51
- /**
52
- * Converts NativescriptFrames to frames in the Sentry format
53
- * @param frames NativescriptFrame[]
54
- */
55
- export function convertNativescriptFramesToSentryFrames ( frames : NativescriptFrame [ ] ) : StackFrame [ ] {
56
- // Below you will find lines marked with :HACK to prevent showing errors in the sentry ui
57
- // But since this is a debug only feature: This is Fine (TM)
58
- return frames . map (
59
- ( frame : NativescriptFrame ) : StackFrame => {
60
- const inApp = ( frame . file && ! frame . file . includes ( 'node_modules' ) ) || ( ! ! frame . column && ! ! frame . lineNumber ) ;
61
- // const inApp =true;
62
- return {
63
- colno : frame . column ,
64
- filename : frame . file ,
65
- function : frame . methodName ,
66
- in_app : inApp ,
67
- lineno : inApp ? frame . lineNumber : undefined , // :HACK
68
- platform : inApp ? 'javascript' : 'node' // :HACK
69
- } ;
42
+ // function createFrame(filename, func, lineno, colno) {
43
+
44
+ function createFrame ( frame : Partial < NativescriptStackFrame > ) {
45
+ frame . in_app = ( frame . filename && ! frame . filename . includes ( 'node_modules' ) ) || ( ! ! frame . colno && ! ! frame . lineno ) ;
46
+ frame . platform = frame . filename . endsWith ( '.js' ) ? 'javascript' : 'android' ;
47
+
48
+
49
+ return frame ;
50
+ }
51
+
52
+ const nativescriptRegex =
53
+ / ^ \s * a t (?: ( .* \) .* ?| .* ?) ? \( ) ? ( (?: f i l e | n a t i v e | w e b p a c k | < a n o n y m o u s > | [ - a - z ] + : | .* b u n d l e | \/ ) ? .* ?) (?: : ( \d + ) ) ? (?: : ( \d + ) ) ? \) ? \s * $ / i;
54
+
55
+ const nativescriptFunc = line => {
56
+ const parts = nativescriptRegex . exec ( line ) ;
57
+ if ( parts ) {
58
+ return createFrame ( {
59
+ filename :parts [ 2 ] ,
60
+ platform :'javascript' ,
61
+ function :parts [ 1 ] || UNKNOWN_FUNCTION ,
62
+ lineno :parts [ 3 ] ? + parts [ 3 ] : undefined ,
63
+ colno :parts [ 4 ] ? + parts [ 4 ] : undefined
64
+ } ) ;
65
+ }
66
+ return null ;
67
+ } ;
68
+
69
+ const nativescriptLineParser : StackLineParser = [ 30 , nativescriptFunc ] ;
70
+
71
+ const androidRegex =
72
+ / ^ \s * (?: ( .* \) .* ?| .* ?) ? \( ) ? ( (?: N a t i v e M e t h o d | [ - a - z ] + : ) ? .* ?) (?: : ( \d + ) ) ? (?: : ( \d + ) ) ? \) ? \s * $ / i;
73
+
74
+ const androidFunc = line => {
75
+ const parts = androidRegex . exec ( line ) ;
76
+ if ( parts ) {
77
+ let func = UNKNOWN_FUNCTION , mod ;
78
+ if ( parts [ 1 ] ) {
79
+ const splitted = parts [ 1 ] . split ( '.' ) ;
80
+ func = splitted [ splitted . length - 1 ] ;
81
+ mod = splitted . slice ( 0 , - 1 ) . join ( '.' ) ;
82
+ }
83
+ if ( ! parts [ 2 ] . endsWith ( '.java' ) ) {
84
+ return null ;
70
85
}
71
- ) ;
86
+ return createFrame ( {
87
+ filename :parts [ 2 ] ,
88
+ function :func ,
89
+ module :mod ,
90
+ native : func && ( func . indexOf ( 'Native Method' ) !== - 1 ) ,
91
+ lineno :parts [ 3 ] ? + parts [ 3 ] : undefined ,
92
+ colno :parts [ 4 ] ? + parts [ 4 ] : undefined
93
+ } ) ;
94
+ }
95
+ return null ;
96
+ } ;
97
+
98
+ const androidLineParser : StackLineParser = [ 50 , androidFunc ] ;
99
+
100
+ const stackParser = stackParserFromStackParserOptions ( [ nativescriptLineParser , androidLineParser ] ) ;
101
+
102
+ export function parseErrorStack ( e : NativescriptError ) : StackFrame [ ] {
103
+ const stack = e ?. [ 'stackTrace' ] || e ?. stack ;
104
+ if ( ! stack ) {
105
+ return [ ] ;
106
+ }
107
+ console . log ( 'parseErrorStack' , stack ) ;
108
+ return stackParser ( stack ) ;
72
109
}
110
+
73
111
/** Tries to symbolicate the JS stack trace on the device. */
74
112
export class DebugSymbolicator implements Integration {
75
113
/**
@@ -92,9 +130,11 @@ export class DebugSymbolicator implements Integration {
92
130
}
93
131
// @ts -ignore
94
132
const error : NativescriptError = hint . originalException ;
95
-
96
133
// const parseErrorStack = require('react-native/Libraries/Core/Devtools/parseErrorStack');
97
134
const stack = parseErrorStack ( error ) ;
135
+ console . log ( 'addGlobalEventProcessor' , error ) ;
136
+ console . log ( 'stack' , stack ) ;
137
+
98
138
99
139
// Ideally this should go into contexts but android sdk doesn't support it
100
140
event . extra = {
@@ -117,12 +157,11 @@ export class DebugSymbolicator implements Integration {
117
157
*/
118
158
private async _symbolicate (
119
159
event : Event ,
120
- stack : NativescriptFrame [ ]
160
+ stack : StackFrame [ ]
121
161
) : Promise < void > {
122
162
try {
123
163
// eslint-disable-next-line @typescript-eslint/no-var-requires
124
- const convertedFrames = convertNativescriptFramesToSentryFrames ( stack ) ;
125
- this . _replaceFramesInEvent ( event , convertedFrames ) ;
164
+ this . _replaceFramesInEvent ( event , stack ) ;
126
165
} catch ( error ) {
127
166
if ( error instanceof Error ) {
128
167
logger . warn ( `Unable to symbolicate stack trace: ${ error . message } ` ) ;
0 commit comments