@@ -4,6 +4,7 @@ import { Subject } from "await-notify";
4
4
import {
5
5
InitializedEvent ,
6
6
LoggingDebugSession ,
7
+ ErrorDestination ,
7
8
OutputEvent ,
8
9
StoppedEvent ,
9
10
ThreadEvent ,
@@ -17,7 +18,7 @@ import { DebugProtocol } from "vscode-debugprotocol";
17
18
import WebSocket = require( "ws" ) ;
18
19
import { AtelierAPI } from "../api" ;
19
20
import * as xdebug from "./xdebugConnection" ;
20
- import { FILESYSTEM_SCHEMA , FILESYSTEM_READONLY_SCHEMA } from "../extension" ;
21
+ import { schemas } from "../extension" ;
21
22
import * as url from "url" ;
22
23
import { DocumentContentProvider } from "../providers/DocumentContentProvider" ;
23
24
import { formatPropertyValue } from "./utils" ;
@@ -40,7 +41,7 @@ interface AttachRequestArguments extends DebugProtocol.AttachRequestArguments {
40
41
export async function convertClientPathToDebugger ( localPath : string , namespace : string ) : Promise < string > {
41
42
const { protocol, pathname, query } = url . parse ( decodeURIComponent ( localPath ) , true , true ) ;
42
43
let fileName = localPath ;
43
- if ( protocol && ( protocol === ` ${ FILESYSTEM_SCHEMA } :` || protocol === ` ${ FILESYSTEM_READONLY_SCHEMA } :` ) ) {
44
+ if ( protocol && schemas . includes ( protocol . slice ( 0 , - 1 ) ) ) {
44
45
if ( query . ns && query . ns !== "" ) {
45
46
namespace = query . ns . toString ( ) ;
46
47
}
@@ -88,6 +89,9 @@ export class ObjectScriptDebugSession extends LoggingDebugSession {
88
89
super ( ) ;
89
90
90
91
const api = new AtelierAPI ( ) ;
92
+ if ( ! api . active ) {
93
+ throw new Error ( "Connection not active" ) ;
94
+ }
91
95
this . _namespace = api . ns ;
92
96
this . _url = api . xdebugUrl ( ) ;
93
97
@@ -141,19 +145,27 @@ export class ObjectScriptDebugSession extends LoggingDebugSession {
141
145
protected async launchRequest ( response : DebugProtocol . LaunchResponse , args : LaunchRequestArguments ) : Promise < void > {
142
146
// this._args = args;
143
147
144
- const debugTarget = `${ this . _namespace } :${ args . program } ` ;
145
- await this . _connection . sendFeatureSetCommand ( "debug_target" , debugTarget ) ;
146
-
147
- this . _debugTargetSet . notify ( ) ;
148
+ try {
149
+ const debugTarget = `${ this . _namespace } :${ args . program } ` ;
150
+ await this . _connection . sendFeatureSetCommand ( "debug_target" , debugTarget ) ;
148
151
152
+ this . _debugTargetSet . notify ( ) ;
153
+ } catch ( error ) {
154
+ this . sendErrorResponse ( response , error ) ;
155
+ return ;
156
+ }
149
157
this . sendResponse ( response ) ;
150
158
}
151
159
152
160
protected async attachRequest ( response : DebugProtocol . AttachResponse , args : AttachRequestArguments ) : Promise < void > {
153
- const debugTarget = `PID:${ args . processId } ` ;
154
- await this . _connection . sendFeatureSetCommand ( "debug_target" , debugTarget ) ;
155
- this . _debugTargetSet . notify ( ) ;
156
-
161
+ try {
162
+ const debugTarget = `PID:${ args . processId } ` ;
163
+ await this . _connection . sendFeatureSetCommand ( "debug_target" , debugTarget ) ;
164
+ this . _debugTargetSet . notify ( ) ;
165
+ } catch ( error ) {
166
+ this . sendErrorResponse ( response , error ) ;
167
+ return ;
168
+ }
157
169
this . sendResponse ( response ) ;
158
170
}
159
171
@@ -202,74 +214,79 @@ export class ObjectScriptDebugSession extends LoggingDebugSession {
202
214
response : DebugProtocol . SetBreakpointsResponse ,
203
215
args : DebugProtocol . SetBreakpointsArguments
204
216
) : Promise < void > {
205
- await this . _debugTargetSet . wait ( 1000 ) ;
206
-
207
- const filePath = args . source . path ;
208
- const uri =
209
- filePath . startsWith ( FILESYSTEM_SCHEMA ) || filePath . startsWith ( FILESYSTEM_READONLY_SCHEMA )
210
- ? vscode . Uri . parse ( filePath )
211
- : vscode . Uri . file ( filePath ) ;
212
- const fileUri = await convertClientPathToDebugger ( args . source . path , this . _namespace ) ;
213
- const [ , fileName ] = fileUri . match ( / \| ( [ ^ | ] + ) $ / ) ;
214
-
215
- const currentList = await this . _connection . sendBreakpointListCommand ( ) ;
216
- currentList . breakpoints
217
- . filter ( ( breakpoint ) => {
218
- if ( breakpoint instanceof xdebug . LineBreakpoint ) {
219
- return breakpoint . fileUri === fileName ;
220
- }
221
- return false ;
222
- } )
223
- . map ( ( breakpoint ) => {
224
- this . _connection . sendBreakpointRemoveCommand ( breakpoint ) ;
225
- } ) ;
226
-
227
- let xdebugBreakpoints : ( xdebug . ConditionalBreakpoint | xdebug . ClassLineBreakpoint | xdebug . LineBreakpoint ) [ ] = [ ] ;
228
- xdebugBreakpoints = await Promise . all (
229
- args . breakpoints . map ( async ( breakpoint ) => {
230
- const line = breakpoint . line ;
231
- if ( breakpoint . condition ) {
232
- return new xdebug . ConditionalBreakpoint ( breakpoint . condition , fileUri , line ) ;
233
- } else if ( fileName . endsWith ( "cls" ) ) {
234
- return await vscode . workspace . openTextDocument ( uri ) . then ( ( document ) => {
235
- const methodMatchPattern = new RegExp ( `^(?:Class)?Method ([^(]+)(?=[( ])` , "i" ) ;
236
- for ( let i = line ; line > 0 ; i -- ) {
237
- const lineOfCode = document . lineAt ( i ) . text ;
238
- const methodMatch = lineOfCode . match ( methodMatchPattern ) ;
239
- if ( methodMatch ) {
240
- const [ , methodName ] = methodMatch ;
241
- return new xdebug . ClassLineBreakpoint ( fileUri , line , methodName , line - i - 2 ) ;
217
+ try {
218
+ await this . _debugTargetSet . wait ( 1000 ) ;
219
+
220
+ const filePath = args . source . path ;
221
+ const { protocol } = url . parse ( decodeURIComponent ( filePath ) , true , true ) ;
222
+ const uri =
223
+ protocol && schemas . includes ( protocol . slice ( 0 , - 1 ) ) ? vscode . Uri . parse ( filePath ) : vscode . Uri . file ( filePath ) ;
224
+ const fileUri = await convertClientPathToDebugger ( args . source . path , this . _namespace ) ;
225
+ const [ , fileName ] = fileUri . match ( / \| ( [ ^ | ] + ) $ / ) ;
226
+
227
+ const currentList = await this . _connection . sendBreakpointListCommand ( ) ;
228
+ currentList . breakpoints
229
+ . filter ( ( breakpoint ) => {
230
+ if ( breakpoint instanceof xdebug . LineBreakpoint ) {
231
+ return breakpoint . fileUri === fileName ;
232
+ }
233
+ return false ;
234
+ } )
235
+ . map ( ( breakpoint ) => {
236
+ this . _connection . sendBreakpointRemoveCommand ( breakpoint ) ;
237
+ } ) ;
238
+
239
+ let xdebugBreakpoints : ( xdebug . ConditionalBreakpoint | xdebug . ClassLineBreakpoint | xdebug . LineBreakpoint ) [ ] = [ ] ;
240
+ xdebugBreakpoints = await Promise . all (
241
+ args . breakpoints . map ( async ( breakpoint ) => {
242
+ const line = breakpoint . line ;
243
+ if ( breakpoint . condition ) {
244
+ return new xdebug . ConditionalBreakpoint ( breakpoint . condition , fileUri , line ) ;
245
+ } else if ( fileName . endsWith ( "cls" ) ) {
246
+ return await vscode . workspace . openTextDocument ( uri ) . then ( ( document ) => {
247
+ const methodMatchPattern = new RegExp ( `^(?:Class)?Method ([^(]+)(?=[( ])` , "i" ) ;
248
+ for ( let i = line ; line > 0 ; i -- ) {
249
+ const lineOfCode = document . lineAt ( i ) . text ;
250
+ const methodMatch = lineOfCode . match ( methodMatchPattern ) ;
251
+ if ( methodMatch ) {
252
+ const [ , methodName ] = methodMatch ;
253
+ return new xdebug . ClassLineBreakpoint ( fileUri , line , methodName , line - i - 2 ) ;
254
+ }
242
255
}
243
- }
244
- } ) ;
245
- } else if ( filePath . endsWith ( "mac" ) || filePath . endsWith ( "int" ) ) {
246
- return new xdebug . RoutineLineBreakpoint ( fileUri , line , "" , line - 1 ) ;
247
- } else {
248
- return new xdebug . LineBreakpoint ( fileUri , line ) ;
249
- }
250
- } )
251
- ) ;
256
+ } ) ;
257
+ } else if ( filePath . endsWith ( "mac" ) || filePath . endsWith ( "int" ) ) {
258
+ return new xdebug . RoutineLineBreakpoint ( fileUri , line , "" , line - 1 ) ;
259
+ } else {
260
+ return new xdebug . LineBreakpoint ( fileUri , line ) ;
261
+ }
262
+ } )
263
+ ) ;
264
+
265
+ const vscodeBreakpoints : DebugProtocol . Breakpoint [ ] = [ ] ;
266
+ await Promise . all (
267
+ xdebugBreakpoints . map ( async ( breakpoint , index ) => {
268
+ try {
269
+ await this . _connection . sendBreakpointSetCommand ( breakpoint ) ;
270
+ vscodeBreakpoints [ index ] = { verified : true , line : breakpoint . line } ;
271
+ } catch ( error ) {
272
+ vscodeBreakpoints [ index ] = {
273
+ verified : false ,
274
+ line : breakpoint . line ,
275
+ message : error . message ,
276
+ } ;
277
+ }
278
+ } )
279
+ ) ;
252
280
253
- const vscodeBreakpoints : DebugProtocol . Breakpoint [ ] = [ ] ;
254
- await Promise . all (
255
- xdebugBreakpoints . map ( async ( breakpoint , index ) => {
256
- try {
257
- await this . _connection . sendBreakpointSetCommand ( breakpoint ) ;
258
- vscodeBreakpoints [ index ] = { verified : true , line : breakpoint . line } ;
259
- } catch ( error ) {
260
- vscodeBreakpoints [ index ] = {
261
- verified : false ,
262
- line : breakpoint . line ,
263
- message : error . message ,
264
- } ;
265
- }
266
- } )
267
- ) ;
281
+ // send back the actual breakpoint positions
282
+ response . body = {
283
+ breakpoints : vscodeBreakpoints ,
284
+ } ;
285
+ } catch ( error ) {
286
+ this . sendErrorResponse ( response , error ) ;
287
+ return ;
288
+ }
268
289
269
- // send back the actual breakpoint positions
270
- response . body = {
271
- breakpoints : vscodeBreakpoints ,
272
- } ;
273
290
this . sendResponse ( response ) ;
274
291
}
275
292
@@ -533,4 +550,30 @@ export class ObjectScriptDebugSession extends LoggingDebugSession {
533
550
} ;
534
551
this . sendResponse ( response ) ;
535
552
}
553
+
554
+ protected sendErrorResponse ( response : DebugProtocol . Response , error : Error , dest ?: ErrorDestination ) : void ;
555
+ protected sendErrorResponse (
556
+ response : DebugProtocol . Response ,
557
+ codeOrMessage : number | DebugProtocol . Message ,
558
+ format ?: string ,
559
+ variables ?: any ,
560
+ dest ?: ErrorDestination
561
+ ) : void ;
562
+ protected sendErrorResponse ( response : DebugProtocol . Response , ...rest ) : void {
563
+ if ( rest [ 0 ] instanceof Error ) {
564
+ const error = rest [ 0 ] as Error & { code ?: number | string ; errno ?: number } ;
565
+ const dest = rest [ 1 ] as ErrorDestination ;
566
+ let code : number ;
567
+ if ( typeof error . code === "number" ) {
568
+ code = error . code as number ;
569
+ } else if ( typeof error . errno === "number" ) {
570
+ code = error . errno ;
571
+ } else {
572
+ code = 0 ;
573
+ }
574
+ super . sendErrorResponse ( response , code , error . message , dest ) ;
575
+ } else {
576
+ super . sendErrorResponse ( response , rest [ 0 ] , rest [ 1 ] , rest [ 2 ] , rest [ 3 ] ) ;
577
+ }
578
+ }
536
579
}
0 commit comments