@@ -4,6 +4,7 @@ import { Subject } from "await-notify";
44import {
55 InitializedEvent ,
66 LoggingDebugSession ,
7+ ErrorDestination ,
78 OutputEvent ,
89 StoppedEvent ,
910 ThreadEvent ,
@@ -17,7 +18,7 @@ import { DebugProtocol } from "vscode-debugprotocol";
1718import WebSocket = require( "ws" ) ;
1819import { AtelierAPI } from "../api" ;
1920import * as xdebug from "./xdebugConnection" ;
20- import { FILESYSTEM_SCHEMA } from "../extension" ;
21+ import { schemas } from "../extension" ;
2122import * as url from "url" ;
2223import { DocumentContentProvider } from "../providers/DocumentContentProvider" ;
2324import { formatPropertyValue } from "./utils" ;
@@ -40,7 +41,7 @@ interface AttachRequestArguments extends DebugProtocol.AttachRequestArguments {
4041export async function convertClientPathToDebugger ( localPath : string , namespace : string ) : Promise < string > {
4142 const { protocol, pathname, query } = url . parse ( decodeURIComponent ( localPath ) , true , true ) ;
4243 let fileName = localPath ;
43- if ( protocol && protocol === ` ${ FILESYSTEM_SCHEMA } :` ) {
44+ if ( protocol && schemas . includes ( protocol . slice ( 0 , - 1 ) ) ) {
4445 if ( query . ns && query . ns !== "" ) {
4546 namespace = query . ns . toString ( ) ;
4647 }
@@ -88,6 +89,9 @@ export class ObjectScriptDebugSession extends LoggingDebugSession {
8889 super ( ) ;
8990
9091 const api = new AtelierAPI ( ) ;
92+ if ( ! api . active ) {
93+ throw new Error ( "Connection not active" ) ;
94+ }
9195 this . _namespace = api . ns ;
9296 this . _url = api . xdebugUrl ( ) ;
9397
@@ -141,19 +145,27 @@ export class ObjectScriptDebugSession extends LoggingDebugSession {
141145 protected async launchRequest ( response : DebugProtocol . LaunchResponse , args : LaunchRequestArguments ) : Promise < void > {
142146 // this._args = args;
143147
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 ) ;
148151
152+ this . _debugTargetSet . notify ( ) ;
153+ } catch ( error ) {
154+ this . sendErrorResponse ( response , error ) ;
155+ return ;
156+ }
149157 this . sendResponse ( response ) ;
150158 }
151159
152160 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+ }
157169 this . sendResponse ( response ) ;
158170 }
159171
@@ -202,71 +214,79 @@ export class ObjectScriptDebugSession extends LoggingDebugSession {
202214 response : DebugProtocol . SetBreakpointsResponse ,
203215 args : DebugProtocol . SetBreakpointsArguments
204216 ) : Promise < void > {
205- await this . _debugTargetSet . wait ( 1000 ) ;
206-
207- const filePath = args . source . path ;
208- const uri = filePath . startsWith ( FILESYSTEM_SCHEMA ) ? vscode . Uri . parse ( filePath ) : vscode . Uri . file ( filePath ) ;
209- const fileUri = await convertClientPathToDebugger ( args . source . path , this . _namespace ) ;
210- const [ , fileName ] = fileUri . match ( / \| ( [ ^ | ] + ) $ / ) ;
211-
212- const currentList = await this . _connection . sendBreakpointListCommand ( ) ;
213- currentList . breakpoints
214- . filter ( ( breakpoint ) => {
215- if ( breakpoint instanceof xdebug . LineBreakpoint ) {
216- return breakpoint . fileUri === fileName ;
217- }
218- return false ;
219- } )
220- . map ( ( breakpoint ) => {
221- this . _connection . sendBreakpointRemoveCommand ( breakpoint ) ;
222- } ) ;
223-
224- let xdebugBreakpoints : ( xdebug . ConditionalBreakpoint | xdebug . ClassLineBreakpoint | xdebug . LineBreakpoint ) [ ] = [ ] ;
225- xdebugBreakpoints = await Promise . all (
226- args . breakpoints . map ( async ( breakpoint ) => {
227- const line = breakpoint . line ;
228- if ( breakpoint . condition ) {
229- return new xdebug . ConditionalBreakpoint ( breakpoint . condition , fileUri , line ) ;
230- } else if ( fileName . endsWith ( "cls" ) ) {
231- return await vscode . workspace . openTextDocument ( uri ) . then ( ( document ) => {
232- const methodMatchPattern = new RegExp ( `^(?:Class)?Method ([^(]+)(?=[( ])` , "i" ) ;
233- for ( let i = line ; line > 0 ; i -- ) {
234- const lineOfCode = document . lineAt ( i ) . text ;
235- const methodMatch = lineOfCode . match ( methodMatchPattern ) ;
236- if ( methodMatch ) {
237- const [ , methodName ] = methodMatch ;
238- 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+ }
239255 }
240- }
241- } ) ;
242- } else if ( filePath . endsWith ( "mac" ) || filePath . endsWith ( "int" ) ) {
243- return new xdebug . RoutineLineBreakpoint ( fileUri , line , "" , line - 1 ) ;
244- } else {
245- return new xdebug . LineBreakpoint ( fileUri , line ) ;
246- }
247- } )
248- ) ;
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+ ) ;
249280
250- const vscodeBreakpoints : DebugProtocol . Breakpoint [ ] = [ ] ;
251- await Promise . all (
252- xdebugBreakpoints . map ( async ( breakpoint , index ) => {
253- try {
254- await this . _connection . sendBreakpointSetCommand ( breakpoint ) ;
255- vscodeBreakpoints [ index ] = { verified : true , line : breakpoint . line } ;
256- } catch ( error ) {
257- vscodeBreakpoints [ index ] = {
258- verified : false ,
259- line : breakpoint . line ,
260- message : error . message ,
261- } ;
262- }
263- } )
264- ) ;
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+ }
265289
266- // send back the actual breakpoint positions
267- response . body = {
268- breakpoints : vscodeBreakpoints ,
269- } ;
270290 this . sendResponse ( response ) ;
271291 }
272292
@@ -530,4 +550,30 @@ export class ObjectScriptDebugSession extends LoggingDebugSession {
530550 } ;
531551 this . sendResponse ( response ) ;
532552 }
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+ }
533579}
0 commit comments