test-infra: fix Semgrep escape hatch and add exception chaining pattern
Fixed two critical issues with the Semgrep rules for broad exception suppression:
1. **Escape hatch mechanism**: Replaced the broken `# error-propagation: allow` comment-based escape hatch with Semgrep's native `# nosemgrep` comment support. Semgrep strips comments from the AST, so pattern-not clauses looking for inline comments never match. The native `# nosemgrep` comment is properly supported by Semgrep and provides a reliable override mechanism.
2. **Missing exception chaining pattern**: Added `raise $EXC from $CAUSE` pattern-not entries for both `Exception` and `BaseException` variants. This prevents false positives when legitimate exception chaining is used (e.g., `raise ServiceError("context") from e`), which is an allowed pattern per CONTRIBUTING.md.
Updated both `python-no-suppressed-exception` and `python-no-suppress-exception` rules with these fixes. The escape hatch now works reliably and exception chaining is properly recognized as an allowed pattern.
ISSUES CLOSED: #9103
This commit is contained in:
+17
-21
@@ -78,6 +78,11 @@ rules:
|
||||
...
|
||||
except Exception:
|
||||
raise $EXC
|
||||
- pattern-not: |
|
||||
try:
|
||||
...
|
||||
except Exception:
|
||||
raise $EXC from $CAUSE
|
||||
- pattern-not: |
|
||||
try:
|
||||
...
|
||||
@@ -88,18 +93,11 @@ rules:
|
||||
...
|
||||
except Exception as $VAR:
|
||||
raise $VAR
|
||||
- pattern-not: |
|
||||
try:
|
||||
...
|
||||
except Exception:
|
||||
# error-propagation: allow
|
||||
...
|
||||
- pattern-not: |
|
||||
try:
|
||||
...
|
||||
except Exception as $VAR:
|
||||
# error-propagation: allow
|
||||
...
|
||||
raise $VAR from $CAUSE
|
||||
- patterns:
|
||||
- pattern: |
|
||||
try:
|
||||
@@ -116,6 +114,11 @@ rules:
|
||||
...
|
||||
except BaseException:
|
||||
raise $EXC
|
||||
- pattern-not: |
|
||||
try:
|
||||
...
|
||||
except BaseException:
|
||||
raise $EXC from $CAUSE
|
||||
- pattern-not: |
|
||||
try:
|
||||
...
|
||||
@@ -126,18 +129,11 @@ rules:
|
||||
...
|
||||
except BaseException as $VAR:
|
||||
raise $VAR
|
||||
- pattern-not: |
|
||||
try:
|
||||
...
|
||||
except BaseException:
|
||||
# error-propagation: allow
|
||||
...
|
||||
- pattern-not: |
|
||||
try:
|
||||
...
|
||||
except BaseException as $VAR:
|
||||
# error-propagation: allow
|
||||
...
|
||||
raise $VAR from $CAUSE
|
||||
message: >
|
||||
Broad exception suppression detected. Do not suppress Exception or BaseException
|
||||
without re-raising or narrowing to a specific exception type.
|
||||
@@ -145,12 +141,12 @@ rules:
|
||||
CRITICAL: Let exceptions propagate to top-level execution (see CONTRIBUTING.md).
|
||||
|
||||
If you have specific recovery logic that justifies suppressing this exception,
|
||||
add the annotation '# error-propagation: allow' on the except line.
|
||||
add the annotation '# nosemgrep' on the except line to disable this rule.
|
||||
|
||||
Example of allowed suppression:
|
||||
try:
|
||||
resource.cleanup()
|
||||
except Exception: # error-propagation: allow
|
||||
except Exception: # nosemgrep
|
||||
pass # Resource already cleaned up; safe to ignore
|
||||
languages: [python]
|
||||
severity: ERROR
|
||||
@@ -164,7 +160,7 @@ rules:
|
||||
- pattern: contextlib.suppress(Exception)
|
||||
- pattern: contextlib.suppress(BaseException)
|
||||
- pattern-not: |
|
||||
# error-propagation: allow
|
||||
# nosemgrep
|
||||
contextlib.suppress(...)
|
||||
message: >
|
||||
Use of contextlib.suppress(Exception) or contextlib.suppress(BaseException)
|
||||
@@ -173,10 +169,10 @@ rules:
|
||||
CRITICAL: Let exceptions propagate to top-level execution (see CONTRIBUTING.md).
|
||||
|
||||
If you have specific recovery logic that justifies suppressing this exception,
|
||||
add the annotation '# error-propagation: allow' on the line above the suppress call.
|
||||
add the annotation '# nosemgrep' on the line above the suppress call.
|
||||
|
||||
Example of allowed suppression:
|
||||
# error-propagation: allow
|
||||
# nosemgrep
|
||||
with contextlib.suppress(Exception):
|
||||
resource.cleanup() # Resource already cleaned up; safe to ignore
|
||||
languages: [python]
|
||||
|
||||
Reference in New Issue
Block a user