wip more informative authrequired error

This commit is contained in:
Owen Lin
2026-01-20 16:23:55 -08:00
parent 4a9c2bcc5a
commit 2aa08e92b2
5 changed files with 382 additions and 64 deletions
@@ -1353,10 +1353,13 @@ impl CodexMessageProcessor {
self.outgoing.send_response(request_id, response).await;
}
Err(err) => {
let error = JSONRPCErrorError {
code: INTERNAL_ERROR_CODE,
message: format!("error creating conversation: {err}"),
data: None,
let error = match err {
CodexErr::AuthRequired => Self::auth_required_error(),
_ => JSONRPCErrorError {
code: INTERNAL_ERROR_CODE,
message: format!("error creating conversation: {err}"),
data: None,
},
};
self.outgoing.send_error(request_id, error).await;
}
@@ -1465,10 +1468,13 @@ impl CodexMessageProcessor {
.await;
}
Err(err) => {
let error = JSONRPCErrorError {
code: INTERNAL_ERROR_CODE,
message: format!("error creating thread: {err}"),
data: None,
let error = match err {
CodexErr::AuthRequired => Self::auth_required_error(),
_ => JSONRPCErrorError {
code: INTERNAL_ERROR_CODE,
message: format!("error creating thread: {err}"),
data: None,
},
};
self.outgoing.send_error(request_id, error).await;
}
@@ -1896,10 +1902,13 @@ impl CodexMessageProcessor {
self.outgoing.send_response(request_id, response).await;
}
Err(err) => {
let error = JSONRPCErrorError {
code: INTERNAL_ERROR_CODE,
message: format!("error resuming thread: {err}"),
data: None,
let error = match err {
CodexErr::AuthRequired => Self::auth_required_error(),
_ => JSONRPCErrorError {
code: INTERNAL_ERROR_CODE,
message: format!("error resuming thread: {err}"),
data: None,
},
};
self.outgoing.send_error(request_id, error).await;
}
@@ -2022,18 +2031,26 @@ impl CodexMessageProcessor {
{
Ok(thread) => thread,
Err(err) => {
let (code, message) = match err {
CodexErr::Io(_) | CodexErr::Json(_) => (
INVALID_REQUEST_ERROR_CODE,
format!("failed to load rollout `{}`: {err}", rollout_path.display()),
),
CodexErr::InvalidRequest(message) => (INVALID_REQUEST_ERROR_CODE, message),
_ => (INTERNAL_ERROR_CODE, format!("error forking thread: {err}")),
};
let error = JSONRPCErrorError {
code,
message,
data: None,
let error = match err {
CodexErr::AuthRequired => Self::auth_required_error(),
CodexErr::Io(_) | CodexErr::Json(_) => JSONRPCErrorError {
code: INVALID_REQUEST_ERROR_CODE,
message: format!(
"failed to load rollout `{}`: {err}",
rollout_path.display()
),
data: None,
},
CodexErr::InvalidRequest(message) => JSONRPCErrorError {
code: INVALID_REQUEST_ERROR_CODE,
message,
data: None,
},
_ => JSONRPCErrorError {
code: INTERNAL_ERROR_CODE,
message: format!("error forking thread: {err}"),
data: None,
},
};
self.outgoing.send_error(request_id, error).await;
return;
@@ -2763,10 +2780,13 @@ impl CodexMessageProcessor {
self.outgoing.send_response(request_id, response).await;
}
Err(err) => {
let error = JSONRPCErrorError {
code: INTERNAL_ERROR_CODE,
message: format!("error resuming conversation: {err}"),
data: None,
let error = match err {
CodexErr::AuthRequired => Self::auth_required_error(),
_ => JSONRPCErrorError {
code: INTERNAL_ERROR_CODE,
message: format!("error resuming conversation: {err}"),
data: None,
},
};
self.outgoing.send_error(request_id, error).await;
}
@@ -2885,21 +2905,26 @@ impl CodexMessageProcessor {
{
Ok(thread) => thread,
Err(err) => {
let (code, message) = match err {
CodexErr::Io(_) | CodexErr::Json(_) => (
INVALID_REQUEST_ERROR_CODE,
format!("failed to load rollout `{}`: {err}", rollout_path.display()),
),
CodexErr::InvalidRequest(message) => (INVALID_REQUEST_ERROR_CODE, message),
_ => (
INTERNAL_ERROR_CODE,
format!("error forking conversation: {err}"),
),
};
let error = JSONRPCErrorError {
code,
message,
data: None,
let error = match err {
CodexErr::AuthRequired => Self::auth_required_error(),
CodexErr::Io(_) | CodexErr::Json(_) => JSONRPCErrorError {
code: INVALID_REQUEST_ERROR_CODE,
message: format!(
"failed to load rollout `{}`: {err}",
rollout_path.display()
),
data: None,
},
CodexErr::InvalidRequest(message) => JSONRPCErrorError {
code: INVALID_REQUEST_ERROR_CODE,
message,
data: None,
},
_ => JSONRPCErrorError {
code: INTERNAL_ERROR_CODE,
message: format!("error forking conversation: {err}"),
data: None,
},
};
self.outgoing.send_error(request_id, error).await;
return;
@@ -2942,6 +2967,15 @@ impl CodexMessageProcessor {
self.outgoing.send_error(request_id, error).await;
}
fn auth_required_error() -> JSONRPCErrorError {
JSONRPCErrorError {
code: INVALID_REQUEST_ERROR_CODE,
message: "OpenAI authentication required. Please login via account/login/start (chatgpt or apiKey)."
.to_string(),
data: None,
}
}
async fn send_internal_error(&self, request_id: RequestId, message: String) {
let error = JSONRPCErrorError {
code: INTERNAL_ERROR_CODE,
@@ -3136,12 +3170,24 @@ impl CodexMessageProcessor {
.collect();
// Submit user input to the conversation.
let _ = conversation
if let Err(err) = conversation
.submit(Op::UserInput {
items: mapped_items,
final_output_json_schema: None,
})
.await;
.await
{
let error = match err {
CodexErr::AuthRequired => Self::auth_required_error(),
_ => JSONRPCErrorError {
code: INTERNAL_ERROR_CODE,
message: format!("failed to send message: {err}"),
data: None,
},
};
self.outgoing.send_error(request_id, error).await;
return;
}
// Acknowledge with an empty result.
self.outgoing
@@ -3185,7 +3231,7 @@ impl CodexMessageProcessor {
})
.collect();
let _ = conversation
if let Err(err) = conversation
.submit(Op::UserTurn {
items: mapped_items,
cwd,
@@ -3196,7 +3242,19 @@ impl CodexMessageProcessor {
summary,
final_output_json_schema: output_schema,
})
.await;
.await
{
let error = match err {
CodexErr::AuthRequired => Self::auth_required_error(),
_ => JSONRPCErrorError {
code: INTERNAL_ERROR_CODE,
message: format!("failed to start turn: {err}"),
data: None,
},
};
self.outgoing.send_error(request_id, error).await;
return;
}
self.outgoing
.send_response(request_id, SendUserTurnResponse {})
@@ -3323,10 +3381,13 @@ impl CodexMessageProcessor {
.await;
}
Err(err) => {
let error = JSONRPCErrorError {
code: INTERNAL_ERROR_CODE,
message: format!("failed to start turn: {err}"),
data: None,
let error = match err {
CodexErr::AuthRequired => Self::auth_required_error(),
_ => JSONRPCErrorError {
code: INTERNAL_ERROR_CODE,
message: format!("failed to start turn: {err}"),
data: None,
},
};
self.outgoing.send_error(request_id, error).await;
}
@@ -3400,10 +3461,13 @@ impl CodexMessageProcessor {
.await;
Ok(())
}
Err(err) => Err(JSONRPCErrorError {
code: INTERNAL_ERROR_CODE,
message: format!("failed to start review: {err}"),
data: None,
Err(err) => Err(match err {
CodexErr::AuthRequired => Self::auth_required_error(),
_ => JSONRPCErrorError {
code: INTERNAL_ERROR_CODE,
message: format!("failed to start review: {err}"),
data: None,
},
}),
}
}
@@ -3443,10 +3507,13 @@ impl CodexMessageProcessor {
.thread_manager
.fork_thread(usize::MAX, config, rollout_path)
.await
.map_err(|err| JSONRPCErrorError {
code: INTERNAL_ERROR_CODE,
message: format!("error creating detached review thread: {err}"),
data: None,
.map_err(|err| match err {
CodexErr::AuthRequired => Self::auth_required_error(),
_ => JSONRPCErrorError {
code: INTERNAL_ERROR_CODE,
message: format!("error creating detached review thread: {err}"),
data: None,
},
})?;
if let Err(err) = self
@@ -3482,10 +3549,13 @@ impl CodexMessageProcessor {
let turn_id = review_thread
.submit(Op::Review { review_request })
.await
.map_err(|err| JSONRPCErrorError {
code: INTERNAL_ERROR_CODE,
message: format!("failed to start detached review turn: {err}"),
data: None,
.map_err(|err| match err {
CodexErr::AuthRequired => Self::auth_required_error(),
_ => JSONRPCErrorError {
code: INTERNAL_ERROR_CODE,
message: format!("failed to start detached review turn: {err}"),
data: None,
},
})?;
let turn = Self::build_review_turn(turn_id, display_text);