Skip to content

Commit

Permalink
fix: ignore exception patterns and namespaces (#892)
Browse files Browse the repository at this point in the history
* fix: Ignore Exception patterns

* Update launch.json
  • Loading branch information
zobo committed Mar 22, 2023
1 parent 69f42bc commit d80aa38
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 4 deletions.
23 changes: 23 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,30 @@
"args": ["out/test", "--no-timeouts", "--colors"],
"cwd": "${workspaceRoot}",
"sourceMaps": true,
"env": {
"VSCODE_DEBUG_PORT": "4711"
},
"outFiles": ["${workspaceFolder}/out/**/*.js"]
}
],
"compounds": [
{
"name": "PHP Debug",
"stopAll": true,
"configurations": ["Debug adapter", "Launch Extension"],
"presentation": {
"group": "0_php",
"order": 1
}
},
{
"name": "Unit tests",
"stopAll": true,
"configurations": ["Debug adapter", "Mocha"],
"presentation": {
"group": "0_php",
"order": 2
}
}
]
}
9 changes: 9 additions & 0 deletions src/ignore.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export function shouldIgnoreException(name: string, patterns: string[]): boolean {
return patterns.some(pattern => name.match(convertPattern(pattern)))
}

function convertPattern(pattern: string): string {
const esc = pattern.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&').replace(/-/g, '\\x2d')
const proc = esc.replace(/\\\*\\\*/g, '.*').replace(/\\\*/g, '[^\\\\]*')
return '^' + proc + '$'
}
3 changes: 2 additions & 1 deletion src/phpDebug.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { ProxyConnect } from './proxyConnect'
import { randomUUID } from 'crypto'
import { getConfiguredEnvironment } from './envfile'
import { XdebugCloudConnection } from './cloud'
import { shouldIgnoreException } from './ignore'

if (process.env['VSCODE_NLS_CONFIG']) {
try {
Expand Down Expand Up @@ -676,7 +677,7 @@ class PhpDebugSession extends vscode.DebugSession {
)) ||
// ignore exception class name
(this._args.ignoreExceptions &&
this._args.ignoreExceptions.some(glob => minimatch(response.exception.name, glob)))
shouldIgnoreException(response.exception.name, this._args.ignoreExceptions))
) {
const response = await connection.sendRunCommand()
await this._checkStatus(response)
Expand Down
2 changes: 1 addition & 1 deletion src/test/adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ describe('PHP Debug Adapter', () => {
it('should not break on exception that matches the ignore pattern', async () => {
const program = path.join(TEST_PROJECT, 'ignore_exception.php')

await client.launch({ program, ignoreExceptions: ['IgnoreException'] })
await client.launch({ program, ignoreExceptions: ['NS1\\NS2\\IgnoreException'] })
await client.setExceptionBreakpointsRequest({ filters: ['*'] })
await Promise.all([client.configurationDoneRequest(), client.waitForEvent('terminated')])
})
Expand Down
42 changes: 42 additions & 0 deletions src/test/ignore.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { assert } from 'chai'
import { describe, it } from 'mocha'
import { shouldIgnoreException } from '../ignore'

describe('ignoreExceptions', () => {
it('should match exact', () => {
assert.isTrue(shouldIgnoreException('BaseException', ['BaseException']))
})
it('should no match exact', () => {
assert.isFalse(shouldIgnoreException('BaseException', ['SomeOtherException']))
})
it('should match wildcard end exact', () => {
assert.isTrue(shouldIgnoreException('BaseException', ['BaseException*']))
})
it('should match wildcard end extra', () => {
assert.isTrue(shouldIgnoreException('BaseExceptionMore', ['BaseException*']))
})
it('should match namespaced exact', () => {
assert.isTrue(shouldIgnoreException('NS1\\BaseException', ['NS1\\BaseException']))
})
it('should match namespaced wildcard exact', () => {
assert.isTrue(shouldIgnoreException('NS1\\BaseException', ['NS1\\BaseException*']))
})
it('should match namespaced wildcard extra', () => {
assert.isTrue(shouldIgnoreException('NS1\\BaseExceptionMore', ['NS1\\BaseException*']))
})
it('should match namespaced wildcard whole level', () => {
assert.isTrue(shouldIgnoreException('NS1\\BaseException', ['NS1\\*']))
})
it('should not match namespaced wildcard more levels', () => {
assert.isFalse(shouldIgnoreException('NS1\\NS2\\BaseException', ['NS1\\*']))
})
it('should match namespaced wildcard in middle', () => {
assert.isTrue(shouldIgnoreException('NS1\\NS2\\BaseException', ['NS1\\*\\BaseException']))
})
it('should match namespaced wildcard multiple', () => {
assert.isTrue(shouldIgnoreException('NS1\\NS2\\NS3\\BaseException', ['NS1\\*\\*\\BaseException']))
})
it('should match namespaced wildcard levels', () => {
assert.isTrue(shouldIgnoreException('NS1\\NS2\\NS3\\BaseException', ['NS1\\**\\BaseException']))
})
})
6 changes: 4 additions & 2 deletions testproject/ignore_exception.php
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
<?php

class IgnoreException extends Exception
namespace NS1\NS2;

class IgnoreException extends \Exception
{}

try {
// see launch.json ignoreExceptions
throw new IgnoreException('this is an ignored exception');
} catch (Exception $e) {
} catch (\Exception $e) {
//
}

0 comments on commit d80aa38

Please sign in to comment.