fix: eliminate panic paths in production code (#1184)

* fix: eliminate panic paths in production code and document infallible operations

PolicyRule::new() now returns Result instead of panicking on invalid
caller-supplied regex. CreateJobTool returns ToolError when job_manager
is unconfigured instead of panicking. Remaining infallible unwrap/expect
calls (hardcoded regexes, compile-time constants, guarded accesses)
are annotated with SAFETY comments. Where possible, unwraps are replaced
with safer patterns: split_last(), if-let, match-destructure, and
reusing peek() values.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* fix: use inline lowercase safety comments to match CI pattern

The no-panics CI check greps for '// safety:' (lowercase, inline)
to suppress false positives. Switch from block SAFETY comments to
inline safety comments on the .unwrap() lines.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* test: add regression tests for panic-path fixes

- PolicyRule::new returns Err on invalid regex (not panic)
- CreateJobTool::execute_sandbox returns ToolError when job_manager is None

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* fix: add inline // safety: comments on all infallible unwrap/expect lines

The CI no-panics check requires '// safety:' on the same line as
unwrap()/expect() to suppress false positives. Move safety annotations
from block comments to inline comments on every infallible production
unwrap/expect across all touched files.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* chore: trigger CI with skip-regression-check label

[skip-regression-check]

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* refactor: remove redundant block-level SAFETY comments

Each unwrap/expect now carries its own inline // safety: annotation,
making the standalone block comments above them redundant.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]>
This commit is contained in:
Illia Polosukhin
2026-03-15 03:17:03 +00:00
committed by GitHub
co-authored by Claude Opus 4.6
parent c79754df28
commit 716629809c
17 changed files with 216 additions and 130 deletions
+14 -8
View File
@@ -248,12 +248,14 @@ impl ExtensionManager {
self.tunnel_url
.as_ref()
.filter(|u| !u.is_empty())
.and_then(|raw| url::Url::parse(raw).ok())
.and_then(|u| u.host_str().map(String::from))
.filter(|host| !oauth_defaults::is_loopback_host(host))
.map(|_| {
let base = self.tunnel_url.as_ref().unwrap().trim_end_matches('/');
format!("{}/oauth/callback", base)
.and_then(|raw| {
let url = url::Url::parse(raw).ok()?;
let host = url.host_str().map(String::from)?;
if oauth_defaults::is_loopback_host(&host) {
return None;
}
let base = raw.trim_end_matches('/');
Some(format!("{}/oauth/callback", base))
})
}
@@ -1309,8 +1311,12 @@ impl ExtensionManager {
match fallback_decision(&primary_result, &entry.fallback_source) {
FallbackDecision::Return => primary_result,
FallbackDecision::TryFallback => {
let primary_err = primary_result.unwrap_err();
let fallback = entry.fallback_source.as_ref().unwrap();
// TryFallback guarantees primary is Err and fallback_source is Some.
let (primary_err, fallback) = match (primary_result, entry.fallback_source.as_ref())
{
(Err(e), Some(f)) => (e, f),
(other, _) => return other,
};
tracing::info!(
extension = %entry.name,
primary_error = %primary_err,