11import { 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' ;
44
55// const INTERNAL_CALLSITES_REGEX = new RegExp(['/Libraries/Renderer/oss/NativescriptRenderer-dev\\.js$', '/Libraries/BatchedBridge/MessageQueue\\.js$'].join('|'));
66
@@ -19,6 +19,7 @@ interface NativescriptFrame {
1919 * React Native Error
2020 */
2121type NativescriptError = Error & {
22+ stackTrace ?: string ;
2223 framesToPop ?: number ;
2324 jsEngine ?: string ;
2425 preventSymbolication ?: boolean ;
@@ -32,44 +33,81 @@ type NativescriptError = Error & {
3233// isComponentError?: boolean,
3334// ...
3435// };
36+ const UNKNOWN_FUNCTION = undefined ;
3537
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 ;
4940}
5041
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 ;
7085 }
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 ) ;
72109}
110+
73111/** Tries to symbolicate the JS stack trace on the device. */
74112export class DebugSymbolicator implements Integration {
75113 /**
@@ -92,9 +130,11 @@ export class DebugSymbolicator implements Integration {
92130 }
93131 // @ts -ignore
94132 const error : NativescriptError = hint . originalException ;
95-
96133 // const parseErrorStack = require('react-native/Libraries/Core/Devtools/parseErrorStack');
97134 const stack = parseErrorStack ( error ) ;
135+ console . log ( 'addGlobalEventProcessor' , error ) ;
136+ console . log ( 'stack' , stack ) ;
137+
98138
99139 // Ideally this should go into contexts but android sdk doesn't support it
100140 event . extra = {
@@ -117,12 +157,11 @@ export class DebugSymbolicator implements Integration {
117157 */
118158 private async _symbolicate (
119159 event : Event ,
120- stack : NativescriptFrame [ ]
160+ stack : StackFrame [ ]
121161 ) : Promise < void > {
122162 try {
123163 // eslint-disable-next-line @typescript-eslint/no-var-requires
124- const convertedFrames = convertNativescriptFramesToSentryFrames ( stack ) ;
125- this . _replaceFramesInEvent ( event , convertedFrames ) ;
164+ this . _replaceFramesInEvent ( event , stack ) ;
126165 } catch ( error ) {
127166 if ( error instanceof Error ) {
128167 logger . warn ( `Unable to symbolicate stack trace: ${ error . message } ` ) ;
0 commit comments