mirror of
https://github.com/Tencent/BrowserSkill.git
synced 2026-10-02 07:34:35 +08:00
fix(cli): clear stale recording state when its session is gone
If the foreground `bsk record start` process is killed and its session later disappears, record-session.json keeps pointing at the dead session. `bsk record stop` then fails with not_found and `bsk record start` refuses to run until the file is removed by hand. When record_stop reports not_found, drop the stale state and say so, so `bsk record stop` is the recovery path its own error message promises. Refs #342
This commit is contained in:
@@ -190,7 +190,8 @@ fn dispatch_stop(args: RecordStopArgs, format: Format) -> Result<(), CliError> {
|
||||
Method::ToolRecordStop,
|
||||
Some(params),
|
||||
TOOL_IPC_TIMEOUT,
|
||||
)?;
|
||||
)
|
||||
.map_err(|err| forget_stale_recording(err, &session_id))?;
|
||||
|
||||
let run_result: Result<(), CliError> = (|| {
|
||||
let exported = export_with_recovery(&args.output, &result.trace)?;
|
||||
@@ -215,6 +216,29 @@ fn dispatch_stop(args: RecordStopArgs, format: Format) -> Result<(), CliError> {
|
||||
render_finish(&trace, &args.output, &exported, format)
|
||||
}
|
||||
|
||||
/// A `not_found` stop means the session or its recording is gone, so the
|
||||
/// saved pointer can never be stopped; drop it so `record start` works again.
|
||||
fn forget_stale_recording(err: CliError, session_id: &str) -> CliError {
|
||||
let CliError::Rpc {
|
||||
code: ErrorCode::NotFound,
|
||||
message,
|
||||
data,
|
||||
source,
|
||||
} = err
|
||||
else {
|
||||
return err;
|
||||
};
|
||||
record_state::clear();
|
||||
CliError::Rpc {
|
||||
code: ErrorCode::NotFound,
|
||||
message: format!(
|
||||
"{message}; cleared the stale recording state for session {session_id}, so `bsk record start` can run again"
|
||||
),
|
||||
data,
|
||||
source,
|
||||
}
|
||||
}
|
||||
|
||||
/// When `record start` omitted `--url` and the default example.com page
|
||||
/// never loaded, rewrite the RPC error so the CLI hint points at `--url`.
|
||||
fn annotate_default_start_page_error(err: CliError, user_url: Option<&str>) -> CliError {
|
||||
@@ -408,6 +432,45 @@ mod tests {
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn stop_of_a_vanished_session_unblocks_record_start() {
|
||||
with_temp_home(|| {
|
||||
record_state::write("megi").unwrap();
|
||||
let err = CliError::from_rpc(bsk_protocol::RpcError {
|
||||
code: ErrorCode::NotFound,
|
||||
message: "session not registered or already stopped".into(),
|
||||
data: None,
|
||||
});
|
||||
|
||||
let err = forget_stale_recording(err, "megi");
|
||||
|
||||
assert_eq!(err.code(), Some(ErrorCode::NotFound));
|
||||
assert!(
|
||||
err.to_string()
|
||||
.contains("cleared the stale recording state")
|
||||
);
|
||||
assert!(record_state::read().is_err());
|
||||
prepare_record_start(Path::new("trace")).unwrap();
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn failed_flush_keeps_the_recording_state_for_a_retry() {
|
||||
with_temp_home(|| {
|
||||
record_state::write("oabu").unwrap();
|
||||
let err = CliError::from_rpc(bsk_protocol::RpcError {
|
||||
code: ErrorCode::ProtocolError,
|
||||
message: "failed to flush recorded steps for session oabu".into(),
|
||||
data: None,
|
||||
});
|
||||
|
||||
let err = forget_stale_recording(err, "oabu");
|
||||
|
||||
assert_eq!(err.code(), Some(ErrorCode::ProtocolError));
|
||||
assert_eq!(record_state::read().unwrap().session_id, "oabu");
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default_output_is_trace_dir() {
|
||||
let args = RecordStopArgs {
|
||||
|
||||
Reference in New Issue
Block a user