Skip to content

Commit 85a28a4

Browse files
authored
fix: Improve init failure handling (#684)
* fix: Auto configure runtimeExecutable when only runtimeArgs are used (built-in web server). * fix: Improve handling of broken clients. * Changelog.
1 parent 282a317 commit 85a28a4

File tree

2 files changed

+89
-62
lines changed

2 files changed

+89
-62
lines changed

CHANGELOG.md

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,28 @@ All notable changes to this project will be documented in this file.
44

55
The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/).
66

7+
## [1.21.1]
8+
9+
### Fixed
10+
11+
- Auto configure runtimeExecutable when only runtimeArgs are used (built-in web server).
12+
- Improve handling of broken clients on failed initPacket.
13+
714
## [1.21.0]
815

16+
### Added
17+
918
- Support for maxConnections limiting how many parallel connections the debug adapter allows.
1019

1120
## [1.20.0]
1221

22+
### Added
23+
1324
- Support no-folder debugging in (purple) VS Code.
1425

1526
## [1.19.0]
1627

17-
## Added
28+
### Added
1829

1930
- Support for PHP 8.1 facets
2031
- Support for Xdebug 3.1 xdebug_notify()
@@ -25,19 +36,19 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
2536

2637
## [1.17.0]
2738

28-
## Added
39+
### Added
2940

3041
- Added logpoint support.
3142

3243
## [1.16.3]
3344

34-
## Fixed
45+
### Fixed
3546

3647
- Fixed semver dependency error.
3748

3849
## [1.16.2]
3950

40-
## Fixed
51+
### Fixed
4152

4253
- Fixed breakpoint and launch initialization order.
4354
- Optimize feature negotiation for known Xdebug version.

src/phpDebug.ts

Lines changed: 74 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -345,73 +345,89 @@ class PhpDebugSession extends vscode.DebugSession {
345345
this.sendEvent(new vscode.OutputEvent(log), true)
346346
}
347347
})
348-
const initPacket = await connection.waitForInitPacket()
348+
try {
349+
const initPacket = await connection.waitForInitPacket()
349350

350-
// support for breakpoints
351-
let feat: xdebug.FeatureGetResponse
352-
const supportedEngine =
353-
initPacket.engineName === 'Xdebug' &&
354-
semver.valid(initPacket.engineVersion, { loose: true }) &&
355-
semver.gte(initPacket.engineVersion, '3.0.0', { loose: true })
356-
if (
357-
supportedEngine ||
358-
((feat = await connection.sendFeatureGetCommand('resolved_breakpoints')) &&
359-
feat.supported === '1')
360-
) {
361-
await connection.sendFeatureSetCommand('resolved_breakpoints', '1')
362-
}
363-
if (
364-
supportedEngine ||
365-
((feat = await connection.sendFeatureGetCommand('notify_ok')) && feat.supported === '1')
366-
) {
367-
await connection.sendFeatureSetCommand('notify_ok', '1')
368-
connection.on('notify_user', notify => this.handleUserNotify(notify, connection))
369-
}
370-
if (
371-
supportedEngine ||
372-
((feat = await connection.sendFeatureGetCommand('extended_properties')) &&
373-
feat.supported === '1')
374-
) {
375-
await connection.sendFeatureSetCommand('extended_properties', '1')
376-
}
351+
// support for breakpoints
352+
let feat: xdebug.FeatureGetResponse
353+
const supportedEngine =
354+
initPacket.engineName === 'Xdebug' &&
355+
semver.valid(initPacket.engineVersion, { loose: true }) &&
356+
semver.gte(initPacket.engineVersion, '3.0.0', { loose: true })
357+
if (
358+
supportedEngine ||
359+
((feat = await connection.sendFeatureGetCommand('resolved_breakpoints')) &&
360+
feat.supported === '1')
361+
) {
362+
await connection.sendFeatureSetCommand('resolved_breakpoints', '1')
363+
}
364+
if (
365+
supportedEngine ||
366+
((feat = await connection.sendFeatureGetCommand('notify_ok')) && feat.supported === '1')
367+
) {
368+
await connection.sendFeatureSetCommand('notify_ok', '1')
369+
connection.on('notify_user', notify => this.handleUserNotify(notify, connection))
370+
}
371+
if (
372+
supportedEngine ||
373+
((feat = await connection.sendFeatureGetCommand('extended_properties')) &&
374+
feat.supported === '1')
375+
) {
376+
await connection.sendFeatureSetCommand('extended_properties', '1')
377+
}
377378

378-
// override features from launch.json
379-
try {
380-
const xdebugSettings = args.xdebugSettings || {}
381-
await Promise.all(
382-
Object.keys(xdebugSettings).map(setting =>
383-
connection.sendFeatureSetCommand(setting, xdebugSettings[setting])
379+
// override features from launch.json
380+
try {
381+
const xdebugSettings = args.xdebugSettings || {}
382+
await Promise.all(
383+
Object.keys(xdebugSettings).map(setting =>
384+
connection.sendFeatureSetCommand(setting, xdebugSettings[setting])
385+
)
384386
)
385-
)
386-
} catch (error) {
387-
throw new Error(
388-
'Error applying xdebugSettings: ' + (error instanceof Error ? error.message : error)
389-
)
390-
}
387+
} catch (error) {
388+
throw new Error(
389+
'Error applying xdebugSettings: ' + (error instanceof Error ? error.message : error)
390+
)
391+
}
391392

392-
this.sendEvent(new vscode.ThreadEvent('started', connection.id))
393+
this.sendEvent(new vscode.ThreadEvent('started', connection.id))
393394

394-
// wait for all breakpoints
395-
await this._donePromise
395+
// wait for all breakpoints
396+
await this._donePromise
396397

397-
let bpa = new BreakpointAdapter(connection, this._breakpointManager)
398-
bpa.on('dapEvent', event => this.sendEvent(event))
399-
this._breakpointAdapters.set(connection, bpa)
400-
// sync breakpoints to connection
401-
await bpa.process()
402-
let xdebugResponse: xdebug.StatusResponse
403-
// either tell VS Code we stopped on entry or run the script
404-
if (this._args.stopOnEntry) {
405-
// do one step to the first statement
406-
this._hasStoppedOnEntry = false
407-
xdebugResponse = await connection.sendStepIntoCommand()
408-
} else {
409-
xdebugResponse = await connection.sendRunCommand()
398+
let bpa = new BreakpointAdapter(connection, this._breakpointManager)
399+
bpa.on('dapEvent', event => this.sendEvent(event))
400+
this._breakpointAdapters.set(connection, bpa)
401+
// sync breakpoints to connection
402+
await bpa.process()
403+
let xdebugResponse: xdebug.StatusResponse
404+
// either tell VS Code we stopped on entry or run the script
405+
if (this._args.stopOnEntry) {
406+
// do one step to the first statement
407+
this._hasStoppedOnEntry = false
408+
xdebugResponse = await connection.sendStepIntoCommand()
409+
} else {
410+
xdebugResponse = await connection.sendRunCommand()
411+
}
412+
this._checkStatus(xdebugResponse)
413+
} catch (error) {
414+
this.sendEvent(
415+
new vscode.OutputEvent(
416+
`Failed initializing connection ${connection.id}: ` +
417+
(error instanceof Error ? error.message : error) +
418+
'\n',
419+
'stderr'
420+
)
421+
)
422+
disposeConnection()
423+
socket.destroy()
410424
}
411-
this._checkStatus(xdebugResponse)
412425
} catch (error) {
413426
this.sendEvent(
414-
new vscode.OutputEvent((error instanceof Error ? error.message : error) + '\n', 'stderr')
427+
new vscode.OutputEvent(
428+
'Error in socket server: ' + (error instanceof Error ? error.message : error) + '\n',
429+
'stderr'
430+
)
415431
)
416432
this.shutdown()
417433
}

0 commit comments

Comments
 (0)