@@ -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 , FILESYSTEM_READONLY_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 } :` || protocol === ` ${ FILESYSTEM_READONLY_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,74 +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 =
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+ }
242255 }
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+ ) ;
252280
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+ }
268289
269- // send back the actual breakpoint positions
270- response . body = {
271- breakpoints : vscodeBreakpoints ,
272- } ;
273290 this . sendResponse ( response ) ;
274291 }
275292
@@ -533,4 +550,30 @@ export class ObjectScriptDebugSession extends LoggingDebugSession {
533550 } ;
534551 this . sendResponse ( response ) ;
535552 }
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+ }
536579}
0 commit comments