fix(#765): login/logout removed_subcommand now has error_kind + non-null hint

This commit is contained in:
YeonGyu-Kim
2026-05-27 01:28:35 +09:00
parent 4ea255ca6a
commit d29a8e216b
3 changed files with 58 additions and 1 deletions

View File

@@ -325,6 +325,9 @@ fn classify_error_kind(message: &str) -> &'static str {
"unknown_plugins_action"
} else if message.starts_with("missing_prompt:") {
"missing_prompt"
} else if message.contains("has been removed.") {
// #765: removed subcommands (login, logout) — hint contains migration guidance
"removed_subcommand"
} else if message.starts_with("unknown_option:") {
"unknown_option"
} else if message.contains("is a slash command")
@@ -1478,8 +1481,9 @@ fn compact_interactive_only_error() -> String {
}
fn removed_auth_surface_error(command_name: &str) -> String {
// #765: two-line format so split_error_hint() extracts hint into JSON envelope
format!(
"`claw {command_name}` has been removed. Set ANTHROPIC_API_KEY or ANTHROPIC_AUTH_TOKEN instead."
"`claw {command_name}` has been removed.\nSet ANTHROPIC_API_KEY or ANTHROPIC_AUTH_TOKEN instead."
)
}
@@ -12930,6 +12934,19 @@ mod tests {
),
"config_parse_error"
);
// #765: removed auth subcommands must classify as removed_subcommand
assert_eq!(
classify_error_kind(
"`claw login` has been removed.\nSet ANTHROPIC_API_KEY or ANTHROPIC_AUTH_TOKEN instead."
),
"removed_subcommand"
);
assert_eq!(
classify_error_kind(
"`claw logout` has been removed.\nSet ANTHROPIC_API_KEY or ANTHROPIC_AUTH_TOKEN instead."
),
"removed_subcommand"
);
}
#[test]

View File

@@ -1865,3 +1865,41 @@ fn config_parse_error_has_typed_error_kind_and_hint_764() {
"malformed settings.json must return non-null hint (#764), got: {hint:?}"
);
}
#[test]
fn login_logout_removed_subcommands_have_error_kind_and_hint_765() {
// #765: `claw login` and `claw logout` are removed; JSON envelope must carry
// error_kind:removed_subcommand + non-null hint pointing to the env var migration.
// Before fix: single-line error string → error_kind:"unknown" + hint:null.
let root = unique_temp_dir("login-logout-removed-765");
fs::create_dir_all(&root).expect("temp dir should exist");
for subcmd in &["login", "logout"] {
let output = run_claw(&root, &["--output-format", "json", subcmd], &[]);
assert!(
!output.status.success(),
"claw {subcmd} should exit non-zero"
);
let stderr = String::from_utf8_lossy(&output.stderr);
let json_line = stderr
.lines()
.find(|l| l.trim_start().starts_with('{'))
.unwrap_or_else(|| panic!("claw {subcmd} stderr should contain a JSON envelope"));
let parsed: serde_json::Value =
serde_json::from_str(json_line).expect("error envelope should be valid JSON");
assert_eq!(
parsed["error_kind"], "removed_subcommand",
"claw {subcmd} must return error_kind:removed_subcommand (#765)"
);
let hint = parsed["hint"].as_str().unwrap_or("");
assert!(
!hint.is_empty(),
"claw {subcmd} must return non-null hint (#765), got: {hint:?}"
);
assert!(
hint.contains("ANTHROPIC_API_KEY") || hint.contains("ANTHROPIC_AUTH_TOKEN"),
"claw {subcmd} hint must mention the env var migration path, got: {hint:?}"
);
}
}