8
8
isFileMatched ,
9
9
matchSentryProject ,
10
10
} from './handler'
11
- import { resolveSettings , Settings } from './settings'
11
+ import { resolveSettings , SentryProject , Settings } from './settings'
12
12
13
13
/**
14
14
* Params derived from the document's URI.
@@ -27,9 +27,19 @@ const SENTRYORGANIZATION = SETTINGSCONFIG['sentry.organization']
27
27
* are set in the sentry extension settings.
28
28
*/
29
29
const COMMON_ERRORLOG_PATTERNS = [
30
+ // typescript/javascript
30
31
/ t h r o w n e w E r r o r + \( [ ' " ] ( [ ^ ' " ] + ) [ ' " ] \) / gi,
31
32
/ c o n s o l e \. ( e r r o r | i n f o | w a r n ) \( [ ' " ` ] ( [ ^ ' " ` ] + ) [ ' " ` ] \) / gi,
33
+ // go
32
34
/ l o g \. ( P r i n t f | P r i n t | P r i n t l n ) \( [ ' " ] ( [ ^ ' " ] + ) [ ' " ] \) / gi,
35
+ / f m t \. E r r o r f \( [ ' " ] ( [ ^ ' " ] + ) [ ' " ] \) / gi,
36
+ / e r r o r s \. N e w \( [ ' " ] ( [ ^ ' " ] + ) [ ' " ] \) / gi,
37
+ / e r r \. m e s s a g e \( [ ' " ` ] ( [ ^ ' " ` ] + ) [ ' " ` ] \) / gi,
38
+ / p a n i c \( [ ' " ] ( [ ^ ' " ] + ) [ ' " ] \) / gi,
39
+ // python
40
+ / r a i s e ( T y p e E r r o r | V a l u e E r r o r ) \( [ ' " ` ] ( [ ^ ' " ` ] + ) [ ' " ` ] \) / gi,
41
+ // java
42
+ / l o g g e r \. ( d e b u g | e r r o r ) \( [ ' " ` ] ( [ ^ ' " ` ] + ) [ ' " ` ] \) ; / gi,
33
43
]
34
44
35
45
export function activate ( context : sourcegraph . ExtensionContext ) : void {
@@ -43,23 +53,30 @@ export function activate(context: sourcegraph.ExtensionContext): void {
43
53
context . subscriptions . add (
44
54
activeEditor . subscribe ( editor => {
45
55
const sentryProjects = SETTINGSCONFIG [ 'sentry.projects' ]
46
- const decorations = getDecorations ( editor , sentryProjects )
47
- editor . setDecorations ( DECORATION_TYPE , decorations )
56
+ if ( editor . document . text ) {
57
+ const decorations = getDecorations ( editor . document . uri , editor . document . text , sentryProjects )
58
+ if ( decorations . length === 0 ) {
59
+ return
60
+ }
61
+ editor . setDecorations ( DECORATION_TYPE , decorations )
62
+ }
48
63
} )
49
64
)
50
65
}
51
66
}
52
67
53
68
/**
54
69
* Get and varify the necessary uri and config data and build the decorations.
55
- * @param editor
56
- * @param sentryProjects
70
+ * @param documentUri the current document's URI
71
+ * @param documentText content of the document being scanned for error handling code
72
+ * @param sentryProjects list of Sentry projects sourced from the user's Sentry extension configurations
57
73
*/
58
74
export function getDecorations (
59
- editor : sourcegraph . CodeEditor ,
60
- sentryProjects : Settings [ 'sentry.projects' ]
75
+ documentUri : string ,
76
+ documentText : string ,
77
+ sentryProjects ?: SentryProject [ ]
61
78
) : sourcegraph . TextDocumentDecoration [ ] {
62
- const params : Params = getParamsFromUriPath ( editor . document . uri )
79
+ const params : Params = getParamsFromUriPath ( documentUri )
63
80
const sentryProject = sentryProjects && matchSentryProject ( params , sentryProjects )
64
81
let missingConfigData : string [ ] = [ ]
65
82
let fileMatched : boolean | null
@@ -75,39 +92,43 @@ export function getDecorations(
75
92
}
76
93
77
94
return decorateEditor (
78
- editor ,
79
95
missingConfigData ,
96
+ documentText ,
80
97
sentryProject . projectId ,
81
98
sentryProject . patternProperties . lineMatches
82
99
)
83
100
}
84
- return decorateEditor ( editor , missingConfigData )
101
+ return decorateEditor ( missingConfigData , documentText )
85
102
}
86
103
87
104
/**
88
105
* Build decorations by matching error handling code with either user config or common error patterns.
89
- * @param editor
90
- * @param missingConfigData
91
- * @param sentryProjectId
92
- * @param lineMatches
106
+ * @param missingConfigData list of missing configs that will appear as a hover warning on the Sentry link
107
+ * @param documentText content of the document being scanned for error handling code
108
+ * @param sentryProjectId Sentry project id retrieved from Sentry extension settings
109
+ * @param lineMatches line patching patterns set in the user's Sentry extension configurations
110
+ * @return a list of decorations to render as links on each matching line
93
111
*/
94
112
// TODO: add tests for that new function (kind of like getBlameDecorations())
95
- function decorateEditor (
96
- editor : sourcegraph . CodeEditor ,
113
+ export function decorateEditor (
97
114
missingConfigData : string [ ] ,
115
+ documentText : string ,
98
116
sentryProjectId ?: string ,
99
117
lineMatches ?: RegExp [ ]
100
118
) : sourcegraph . TextDocumentDecoration [ ] {
101
119
const decorations : sourcegraph . TextDocumentDecoration [ ] = [ ]
102
-
103
- for ( const [ index , line ] of editor . document . text ! . split ( '\n' ) . entries ( ) ) {
120
+ for ( const [ index , line ] of documentText . split ( '\n' ) . entries ( ) ) {
104
121
let match : RegExpExecArray | null
105
- for ( let pattern of lineMatches ? lineMatches : COMMON_ERRORLOG_PATTERNS ) {
122
+ for ( let pattern of lineMatches && lineMatches . length > 0 ? lineMatches : COMMON_ERRORLOG_PATTERNS ) {
106
123
pattern = new RegExp ( pattern , 'gi' )
107
124
do {
108
125
match = pattern . exec ( line )
109
- if ( match ) {
110
- decorations . push ( decorateLine ( index , match , missingConfigData , sentryProjectId ) )
126
+ // Depending on the line matching pattern the query m is indexed in position 1 or 2.
127
+ // TODO: Specify which capture group should be used through configuration.
128
+ if ( match && match . length <= 2 ) {
129
+ decorations . push ( decorateLine ( index , match [ 1 ] , missingConfigData , sentryProjectId ) )
130
+ } else if ( match && match . length > 2 ) {
131
+ decorations . push ( decorateLine ( index , match [ 2 ] , missingConfigData , sentryProjectId ) )
111
132
}
112
133
} while ( match )
113
134
pattern . lastIndex = 0 // reset
@@ -121,11 +142,13 @@ function decorateEditor(
121
142
* or that matches common error loggin patterns.
122
143
* @param index for decoration range
123
144
* @param match for a line containing an error query
145
+ * @param missingConfigData list of missing configs that will appear as a hover warning on the Sentry link
124
146
* @param sentryProjectId Sentry project id retrieved from Sentry extension settings
147
+ * @return either a successful or a warning decoration to render the Sentry link
125
148
*/
126
149
export function decorateLine (
127
150
index : number ,
128
- match : RegExpExecArray ,
151
+ match : string ,
129
152
missingConfigData : string [ ] ,
130
153
sentryProjectId ?: string
131
154
) : sourcegraph . TextDocumentDecoration {
@@ -134,19 +157,17 @@ export function decorateLine(
134
157
range : new sourcegraph . Range ( index , 0 , index , 0 ) ,
135
158
isWholeLine : true ,
136
159
after : {
137
- backgroundColor : missingConfigData . length === 0 ? '#e03e2f' : '#f2736d' ,
160
+ backgroundColor : missingConfigData . length === 0 && sentryProjectId ? '#e03e2f' : '#f2736d' ,
138
161
color : 'rgba(255, 255, 255, 0.8)' ,
139
162
contentText : lineDecorationText . content ,
140
163
hoverMessage : lineDecorationText . hover ,
141
- // Depending on the line matching pattern the query m is indexed in position 1 or 2.
142
- // TODO: Specify which capture group should be used through configuration.
143
164
// TODO: If !SENTRYORGANIZATION is missing in config, link to $USER/settings and hint
144
165
// user to fill it out.
145
166
linkURL : ! SENTRYORGANIZATION
146
167
? ''
147
168
: sentryProjectId
148
- ? buildUrl ( match . length > 2 ? match [ 2 ] : match [ 1 ] , sentryProjectId ) . toString ( )
149
- : buildUrl ( match . length > 2 ? match [ 2 ] : match [ 1 ] ) . toString ( ) ,
169
+ ? buildUrl ( match , sentryProjectId ) . toString ( )
170
+ : buildUrl ( match ) . toString ( ) ,
150
171
} ,
151
172
}
152
173
return decoration
0 commit comments