Skip to content

Add new MissingTryBlock rule - #2179

Merged
Andy Jordan (andyleejordan) merged 16 commits into
PowerShell:mainfrom
iRon7:#2098MissingTryBlock
May 15, 2026
Merged

Add new MissingTryBlock rule#2179
Andy Jordan (andyleejordan) merged 16 commits into
PowerShell:mainfrom
iRon7:#2098MissingTryBlock

Conversation

@iRon7

@iRon7iRon7 commented Apr 22, 2026

Copy link
Copy Markdown
Contributor

PR Summary

Although #2098 didn't get an up-for-graps label, I did create the suggested Add new MissingTryBlock rule to warn when catch or finally blocks are not preceded by a try block because:

  • I think that a catch block that misses a try block is less valid than a try block that misses a catch block which causes an parse error by the engine
    • and therefore even deserves the severity Error
  • A missing try block might easily get unnoticed during design time but will very likely fail during runtime
  • It happened twice now that someone in our company tried to publish a script that was missing a try block

Closes#1700 and Fixes#2098

PR Checklist

@iRon7iRon7 changed the title #2098 Add new MissingTryBlock ruleAdd new MissingTryBlock ruleApr 22, 2026
@liamjpeters

Copy link
Copy Markdown
Contributor

👋

This rule has a severity of Warning but is emitting a diagnostic of Error severity. Where this is the only diagnostic that your rule emits, these should match. I would suggest Warning - just because it's not the 99% use-case, doesn't mean I can't define a function called catch and have it accept a ScriptBlock if I wanted to.

This has the same copy-pasta as your other PR.

@iRon7iRon7 changed the title Add new MissingTryBlock ruleWIP: Add new MissingTryBlock ruleApr 28, 2026
…in the rule definition and resolved copy-pasta in the rule description.
Co-authored-by: Copilot <copilot@github.com>
CopilotAI review requested due to automatic review settings April 29, 2026 14:49
@iRon7iRon7 changed the title WIP: Add new MissingTryBlock ruleAdd new MissingTryBlock ruleApr 29, 2026

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new built-in PSScriptAnalyzer rule to detect catch/finally blocks used without a preceding try, with accompanying documentation and Pester tests to validate behavior.

Changes:

  • Introduces the new MissingTryBlock built-in rule implementation and localized strings.
  • Adds rule documentation and registers it in the rules documentation index.
  • Adds a dedicated Pester test suite for violation, compliant, and suppression scenarios.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 6 comments.

Show a summary per file
FileDescription
docs/Rules/README.mdAdds MissingTryBlock to the published rules index table.
docs/Rules/MissingTryBlock.mdNew rule documentation page describing intent, guidance, and examples.
Tests/Rules/MissingTryBlock.tests.ps1New Pester coverage for violations, compliant cases, and suppression behavior.
Rules/Strings.resxAdds name/common-name/description/error message resources for the new rule.
Rules/MissingTryBlock.csImplements AST-based detection and emits diagnostics for missing try before catch/finally.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment threadTests/Rules/MissingTryBlock.tests.ps1
Comment threaddocs/Rules/MissingTryBlock.md Outdated
Comment threadRules/Strings.resx Outdated
Comment threadRules/MissingTryBlock.cs Outdated
Comment threadRules/MissingTryBlock.cs Outdated
Comment threadRules/MissingTryBlock.cs Outdated
iRon7and others added 6 commits April 29, 2026 17:37
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

@andyleejordanAndy Jordan (andyleejordan) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks again iRon7 for working through this with Liam Peters (@liamjpeters). The severity mismatch is fixed and the implementation is tight (using StringConstantExpressionAst as the bareword detection is the right approach for this scenario).

One context note that may be useful: this rule was explicitly endorsed upstream in PowerShell/PowerShell#25491 by the engine working group as something that belongs in PSSA rather than the parser. Good signal that there's appetite for landing it.

Three things before I'm comfortable merging:

The // Find all FunctionDefinitionAst in the Ast comment. GitHub's review bot flagged this and you replied "Outdated?" — but the comment is still in Rules/MissingTryBlock.cs on the current head and it's misleading: the code is finding StringConstantExpressionAst, not FunctionDefinitionAst. Could you replace it with something like // Find bareword "catch" or "finally" tokens that are not part of a TryStatementAst?

Opt-in by default. Same convention point as the other rules: please derive from ConfigurableRule with Enable = false so users can opt in, and update docs/Rules/README.md.

Doc the false-positive. This rule will fire on user code like:

functioncatch { param([scriptblock]$body) &$body }
catch { Write-Host'hi' }

which is legal PowerShell (catch is not a reserved word at the command position). Worth a short note in docs/Rules/MissingTryBlock.md so users know they may need to suppress in unusual cases. Doesn't change the implementation.

Once those are sorted, I'd like Liam Peters (@liamjpeters) to take a quick second look since he did the bulk of the original review.

Drafted by Copilot (Claude Opus 4.7)

Comment threaddocs/Rules/MissingTryBlock.md Outdated
Co-authored-by: Sean Wheeler <sean.wheeler@microsoft.com>

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me but agree to fix things from previous comment

iRon7 added 2 commits May 12, 2026 13:52
… being enabled by default, and to add a note about potential false positives with functions named "catch" or "finally". Also added a test context for when the rule is disabled. Updated the rule implementation to inherit from ConfigurableRule and set Enable to false in the constructor. Updated the AnalyzeScript method to be an override, and added overrides for GetCommonName, GetDescription, GetName, GetSeverity, and GetSourceName.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just some small cosmetic/hygiene changes. The actual rule and test coverage is looking really good 👍

Comment threaddocs/Rules/MissingTryBlock.md Outdated
Comment threadTests/Rules/MissingTryBlock.tests.ps1 Outdated
Comment threadRules/MissingTryBlock.cs Outdated
Comment threadRules/MissingTryBlock.cs Outdated
@liamjpeters

Copy link
Copy Markdown
Contributor

iRon7 - You could update your PR description to include the issues it resolves so they're auto-resolved when your PR is merged.

You can make links using comments in the PR description such as:

Closes #1700 and Fixes #2098

iRon7and others added 2 commits May 15, 2026 19:05
Co-authored-by: Liam Peters <liamjpeters@gmail.com>
Co-authored-by: Liam Peters <liamjpeters@gmail.com>
iRon7and others added 2 commits May 15, 2026 19:06
Co-authored-by: Liam Peters <liamjpeters@gmail.com>
Co-authored-by: Liam Peters <liamjpeters@gmail.com>
@iRon7

Copy link
Copy Markdown
ContributorAuthor

Liam Peters (@liamjpeters),

Thanks again for your comments, I have tested and committed them.

Closes #1700 and Fixes #2098

Added to the PR description (I wasn't even aware of the duplicate 1700)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks iRon7 — and thanks Liam Peters (@liamjpeters) for the careful second pass. All five of Liam's 2026-05-15 line-level asks landed at the new head: the PSMissingTryBlock = @{ settings example, the "Doesn't emit a violation" rename, the duplicate <summary> block above the class, the dead helper, and Closes #1700 and Fixes #2098 in the PR body.

CI is green on Linux, macOS, and Windows. Approving.

Drafted by Copilot (Claude Opus 4.7)

@andyleejordan
Andy Jordan (andyleejordan) merged commit 97f30d6 into PowerShell:mainMay 15, 2026
4 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Rule request: The Catch (or Finally) statement is missing its Try block. Missing try{} block not reported as a problem

6 participants

@iRon7@liamjpeters@andyleejordan@bergmeister@sdwheeler