Skip to content

Commit d80aa38

Browse files
committed
fix: ignore exception patterns and namespaces (#892)
* fix: Ignore Exception patterns * Update launch.json
1 parent 69f42bc commit d80aa38

File tree

6 files changed

+81
-4
lines changed

6 files changed

+81
-4
lines changed

.vscode/launch.json

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,30 @@
3131
"args": ["out/test", "--no-timeouts", "--colors"],
3232
"cwd": "${workspaceRoot}",
3333
"sourceMaps": true,
34+
"env": {
35+
"VSCODE_DEBUG_PORT": "4711"
36+
},
3437
"outFiles": ["${workspaceFolder}/out/**/*.js"]
3538
}
39+
],
40+
"compounds": [
41+
{
42+
"name": "PHP Debug",
43+
"stopAll": true,
44+
"configurations": ["Debug adapter", "Launch Extension"],
45+
"presentation": {
46+
"group": "0_php",
47+
"order": 1
48+
}
49+
},
50+
{
51+
"name": "Unit tests",
52+
"stopAll": true,
53+
"configurations": ["Debug adapter", "Mocha"],
54+
"presentation": {
55+
"group": "0_php",
56+
"order": 2
57+
}
58+
}
3659
]
3760
}

src/ignore.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
export function shouldIgnoreException(name: string, patterns: string[]): boolean {
2+
return patterns.some(pattern => name.match(convertPattern(pattern)))
3+
}
4+
5+
function convertPattern(pattern: string): string {
6+
const esc = pattern.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&').replace(/-/g, '\\x2d')
7+
const proc = esc.replace(/\\\*\\\*/g, '.*').replace(/\\\*/g, '[^\\\\]*')
8+
return '^' + proc + '$'
9+
}

src/phpDebug.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { ProxyConnect } from './proxyConnect'
1818
import { randomUUID } from 'crypto'
1919
import { getConfiguredEnvironment } from './envfile'
2020
import { XdebugCloudConnection } from './cloud'
21+
import { shouldIgnoreException } from './ignore'
2122

2223
if (process.env['VSCODE_NLS_CONFIG']) {
2324
try {
@@ -676,7 +677,7 @@ class PhpDebugSession extends vscode.DebugSession {
676677
)) ||
677678
// ignore exception class name
678679
(this._args.ignoreExceptions &&
679-
this._args.ignoreExceptions.some(glob => minimatch(response.exception.name, glob)))
680+
shouldIgnoreException(response.exception.name, this._args.ignoreExceptions))
680681
) {
681682
const response = await connection.sendRunCommand()
682683
await this._checkStatus(response)

src/test/adapter.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ describe('PHP Debug Adapter', () => {
215215
it('should not break on exception that matches the ignore pattern', async () => {
216216
const program = path.join(TEST_PROJECT, 'ignore_exception.php')
217217

218-
await client.launch({ program, ignoreExceptions: ['IgnoreException'] })
218+
await client.launch({ program, ignoreExceptions: ['NS1\\NS2\\IgnoreException'] })
219219
await client.setExceptionBreakpointsRequest({ filters: ['*'] })
220220
await Promise.all([client.configurationDoneRequest(), client.waitForEvent('terminated')])
221221
})

src/test/ignore.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { assert } from 'chai'
2+
import { describe, it } from 'mocha'
3+
import { shouldIgnoreException } from '../ignore'
4+
5+
describe('ignoreExceptions', () => {
6+
it('should match exact', () => {
7+
assert.isTrue(shouldIgnoreException('BaseException', ['BaseException']))
8+
})
9+
it('should no match exact', () => {
10+
assert.isFalse(shouldIgnoreException('BaseException', ['SomeOtherException']))
11+
})
12+
it('should match wildcard end exact', () => {
13+
assert.isTrue(shouldIgnoreException('BaseException', ['BaseException*']))
14+
})
15+
it('should match wildcard end extra', () => {
16+
assert.isTrue(shouldIgnoreException('BaseExceptionMore', ['BaseException*']))
17+
})
18+
it('should match namespaced exact', () => {
19+
assert.isTrue(shouldIgnoreException('NS1\\BaseException', ['NS1\\BaseException']))
20+
})
21+
it('should match namespaced wildcard exact', () => {
22+
assert.isTrue(shouldIgnoreException('NS1\\BaseException', ['NS1\\BaseException*']))
23+
})
24+
it('should match namespaced wildcard extra', () => {
25+
assert.isTrue(shouldIgnoreException('NS1\\BaseExceptionMore', ['NS1\\BaseException*']))
26+
})
27+
it('should match namespaced wildcard whole level', () => {
28+
assert.isTrue(shouldIgnoreException('NS1\\BaseException', ['NS1\\*']))
29+
})
30+
it('should not match namespaced wildcard more levels', () => {
31+
assert.isFalse(shouldIgnoreException('NS1\\NS2\\BaseException', ['NS1\\*']))
32+
})
33+
it('should match namespaced wildcard in middle', () => {
34+
assert.isTrue(shouldIgnoreException('NS1\\NS2\\BaseException', ['NS1\\*\\BaseException']))
35+
})
36+
it('should match namespaced wildcard multiple', () => {
37+
assert.isTrue(shouldIgnoreException('NS1\\NS2\\NS3\\BaseException', ['NS1\\*\\*\\BaseException']))
38+
})
39+
it('should match namespaced wildcard levels', () => {
40+
assert.isTrue(shouldIgnoreException('NS1\\NS2\\NS3\\BaseException', ['NS1\\**\\BaseException']))
41+
})
42+
})

testproject/ignore_exception.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
<?php
22

3-
class IgnoreException extends Exception
3+
namespace NS1\NS2;
4+
5+
class IgnoreException extends \Exception
46
{}
57

68
try {
79
// see launch.json ignoreExceptions
810
throw new IgnoreException('this is an ignored exception');
9-
} catch (Exception $e) {
11+
} catch (\Exception $e) {
1012
//
1113
}

0 commit comments

Comments
 (0)