bugfix: additional error handling logic for model errors that occur in stream (#203)
**What is added?** Additional error handling functionality is added before the errors are thrown to be handled by upstream handlers. The changes improves the user experience and make the error handling smoother (and more informative). **Why is it added?** Before this addition, when a user tried to use a model they needed previous setup for, the program crashed. This is not necessary here, and informative message is sufficient and enhances user experience. This adheres to the specifications stated in the code file as well by not masking potential logical error detection. Following is before and after:   Moreover, AFAIK no logic was present to handle this or a similar issue in upstream handlers. **How is it scoped? Why won't this mask other errors?** The new brach triggers *only* for `invalid_request_error` events whose `code` is model related (`model_not_found`) This also doesn't prevent the detection (for the case of masking logical errors) of wrong model names, as they would have been caught earlier on. The code passes test, lint and type checks. I believe relevant documentation is added, but I would be more than happy to do further fixes in the code if necessary.
This commit is contained in:
committed by
GitHub
parent
639c67b909
commit
4e7403e5ea
@@ -902,6 +902,7 @@ export class AgentLoop {
|
||||
// (e.g. ECONNRESET, ETIMEDOUT …)
|
||||
// • the OpenAI SDK attached an HTTP `status` >= 500 indicating a
|
||||
// server‑side problem.
|
||||
// • the error is model specific and detected in stream.
|
||||
// If matched we emit a single system message to inform the user and
|
||||
// resolve gracefully so callers can choose to retry.
|
||||
// -------------------------------------------------------------------
|
||||
@@ -984,6 +985,74 @@ export class AgentLoop {
|
||||
return;
|
||||
}
|
||||
|
||||
const isInvalidRequestError = () => {
|
||||
if (!err || typeof err !== "object") {
|
||||
return false;
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const e: any = err;
|
||||
|
||||
if (
|
||||
e.type === "invalid_request_error" &&
|
||||
e.code === "model_not_found"
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (
|
||||
e.cause &&
|
||||
e.cause.type === "invalid_request_error" &&
|
||||
e.cause.code === "model_not_found"
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
if (isInvalidRequestError()) {
|
||||
try {
|
||||
// Extract request ID and error details from the error object
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const e: any = err;
|
||||
|
||||
const reqId =
|
||||
e.request_id ??
|
||||
(e.cause && e.cause.request_id) ??
|
||||
(e.cause && e.cause.requestId);
|
||||
|
||||
const errorDetails = [
|
||||
`Status: ${e.status || (e.cause && e.cause.status) || "unknown"}`,
|
||||
`Code: ${e.code || (e.cause && e.cause.code) || "unknown"}`,
|
||||
`Type: ${e.type || (e.cause && e.cause.type) || "unknown"}`,
|
||||
`Message: ${
|
||||
e.message || (e.cause && e.cause.message) || "unknown"
|
||||
}`,
|
||||
].join(", ");
|
||||
|
||||
const msgText = `⚠️ OpenAI rejected the request${
|
||||
reqId ? ` (request ID: ${reqId})` : ""
|
||||
}. Error details: ${errorDetails}. Please verify your settings and try again.`;
|
||||
|
||||
this.onItem({
|
||||
id: `error-${Date.now()}`,
|
||||
type: "message",
|
||||
role: "system",
|
||||
content: [
|
||||
{
|
||||
type: "input_text",
|
||||
text: msgText,
|
||||
},
|
||||
],
|
||||
});
|
||||
} catch {
|
||||
/* best-effort */
|
||||
}
|
||||
this.onLoading(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// Re‑throw all other errors so upstream handlers can decide what to do.
|
||||
throw err;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user