chore: Enable "curly" rule to avoid single-statement if confusion/errors.

This commit is contained in:
cpojer
2026-01-31 16:19:20 +09:00
parent 009b16fab8
commit 5ceff756e1
1266 changed files with 27871 additions and 9393 deletions

View File

@@ -5,7 +5,9 @@ import { formatSandboxToolPolicyBlockedMessage } from "../sandbox.js";
import type { FailoverReason } from "./types.js";
export function isContextOverflowError(errorMessage?: string): boolean {
if (!errorMessage) return false;
if (!errorMessage) {
return false;
}
const lower = errorMessage.toLowerCase();
const hasRequestSizeExceeds = lower.includes("request size exceeds");
const hasContextWindow =
@@ -30,15 +32,25 @@ const CONTEXT_OVERFLOW_HINT_RE =
/context.*overflow|context window.*(too (?:large|long)|exceed|over|limit|max(?:imum)?|requested|sent|tokens)|(?:prompt|request|input).*(too (?:large|long)|exceed|over|limit|max(?:imum)?)/i;
export function isLikelyContextOverflowError(errorMessage?: string): boolean {
if (!errorMessage) return false;
if (CONTEXT_WINDOW_TOO_SMALL_RE.test(errorMessage)) return false;
if (isContextOverflowError(errorMessage)) return true;
if (!errorMessage) {
return false;
}
if (CONTEXT_WINDOW_TOO_SMALL_RE.test(errorMessage)) {
return false;
}
if (isContextOverflowError(errorMessage)) {
return true;
}
return CONTEXT_OVERFLOW_HINT_RE.test(errorMessage);
}
export function isCompactionFailureError(errorMessage?: string): boolean {
if (!errorMessage) return false;
if (!isContextOverflowError(errorMessage)) return false;
if (!errorMessage) {
return false;
}
if (!isContextOverflowError(errorMessage)) {
return false;
}
const lower = errorMessage.toLowerCase();
return (
lower.includes("summarization failed") ||
@@ -73,15 +85,21 @@ const HTTP_ERROR_HINTS = [
];
function stripFinalTagsFromText(text: string): string {
if (!text) return text;
if (!text) {
return text;
}
return text.replace(FINAL_TAG_RE, "");
}
function collapseConsecutiveDuplicateBlocks(text: string): string {
const trimmed = text.trim();
if (!trimmed) return text;
if (!trimmed) {
return text;
}
const blocks = trimmed.split(/\n{2,}/);
if (blocks.length < 2) return text;
if (blocks.length < 2) {
return text;
}
const normalizeBlock = (value: string) => value.trim().replace(/\s+/g, " ");
const result: string[] = [];
@@ -96,15 +114,21 @@ function collapseConsecutiveDuplicateBlocks(text: string): string {
lastNormalized = normalized;
}
if (result.length === blocks.length) return text;
if (result.length === blocks.length) {
return text;
}
return result.join("\n\n");
}
function isLikelyHttpErrorText(raw: string): boolean {
const match = raw.match(HTTP_STATUS_PREFIX_RE);
if (!match) return false;
if (!match) {
return false;
}
const code = Number(match[1]);
if (!Number.isFinite(code) || code < 400) return false;
if (!Number.isFinite(code) || code < 400) {
return false;
}
const message = match[2].toLowerCase();
return HTTP_ERROR_HINTS.some((hint) => message.includes(hint));
}
@@ -112,10 +136,16 @@ function isLikelyHttpErrorText(raw: string): boolean {
type ErrorPayload = Record<string, unknown>;
function isErrorPayloadObject(payload: unknown): payload is ErrorPayload {
if (!payload || typeof payload !== "object" || Array.isArray(payload)) return false;
if (!payload || typeof payload !== "object" || Array.isArray(payload)) {
return false;
}
const record = payload as ErrorPayload;
if (record.type === "error") return true;
if (typeof record.request_id === "string" || typeof record.requestId === "string") return true;
if (record.type === "error") {
return true;
}
if (typeof record.request_id === "string" || typeof record.requestId === "string") {
return true;
}
if ("error" in record) {
const err = record.error;
if (err && typeof err === "object" && !Array.isArray(err)) {
@@ -133,18 +163,26 @@ function isErrorPayloadObject(payload: unknown): payload is ErrorPayload {
}
function parseApiErrorPayload(raw: string): ErrorPayload | null {
if (!raw) return null;
if (!raw) {
return null;
}
const trimmed = raw.trim();
if (!trimmed) return null;
if (!trimmed) {
return null;
}
const candidates = [trimmed];
if (ERROR_PAYLOAD_PREFIX_RE.test(trimmed)) {
candidates.push(trimmed.replace(ERROR_PAYLOAD_PREFIX_RE, "").trim());
}
for (const candidate of candidates) {
if (!candidate.startsWith("{") || !candidate.endsWith("}")) continue;
if (!candidate.startsWith("{") || !candidate.endsWith("}")) {
continue;
}
try {
const parsed = JSON.parse(candidate) as unknown;
if (isErrorPayloadObject(parsed)) return parsed;
if (isErrorPayloadObject(parsed)) {
return parsed;
}
} catch {
// ignore parse errors
}
@@ -166,9 +204,13 @@ function stableStringify(value: unknown): string {
}
export function getApiErrorPayloadFingerprint(raw?: string): string | null {
if (!raw) return null;
if (!raw) {
return null;
}
const payload = parseApiErrorPayload(raw);
if (!payload) return null;
if (!payload) {
return null;
}
return stableStringify(payload);
}
@@ -184,9 +226,13 @@ export type ApiErrorInfo = {
};
export function parseApiErrorInfo(raw?: string): ApiErrorInfo | null {
if (!raw) return null;
if (!raw) {
return null;
}
const trimmed = raw.trim();
if (!trimmed) return null;
if (!trimmed) {
return null;
}
let httpCode: string | undefined;
let candidate = trimmed;
@@ -198,7 +244,9 @@ export function parseApiErrorInfo(raw?: string): ApiErrorInfo | null {
}
const payload = parseApiErrorPayload(candidate);
if (!payload) return null;
if (!payload) {
return null;
}
const requestId =
typeof payload.request_id === "string"
@@ -214,9 +262,15 @@ export function parseApiErrorInfo(raw?: string): ApiErrorInfo | null {
let errMessage: string | undefined;
if (payload.error && typeof payload.error === "object" && !Array.isArray(payload.error)) {
const err = payload.error as Record<string, unknown>;
if (typeof err.type === "string") errType = err.type;
if (typeof err.code === "string" && !errType) errType = err.code;
if (typeof err.message === "string") errMessage = err.message;
if (typeof err.type === "string") {
errType = err.type;
}
if (typeof err.code === "string" && !errType) {
errType = err.code;
}
if (typeof err.message === "string") {
errMessage = err.message;
}
}
return {
@@ -229,7 +283,9 @@ export function parseApiErrorInfo(raw?: string): ApiErrorInfo | null {
export function formatRawAssistantErrorForUi(raw?: string): string {
const trimmed = (raw ?? "").trim();
if (!trimmed) return "LLM request failed with an unknown error.";
if (!trimmed) {
return "LLM request failed with an unknown error.";
}
const httpMatch = trimmed.match(HTTP_STATUS_PREFIX_RE);
if (httpMatch) {
@@ -256,8 +312,12 @@ export function formatAssistantErrorText(
): string | undefined {
// Also format errors if errorMessage is present, even if stopReason isn't "error"
const raw = (msg.errorMessage ?? "").trim();
if (msg.stopReason !== "error" && !raw) return undefined;
if (!raw) return "LLM request failed with an unknown error.";
if (msg.stopReason !== "error" && !raw) {
return undefined;
}
if (!raw) {
return "LLM request failed with an unknown error.";
}
const unknownTool =
raw.match(/unknown tool[:\s]+["']?([a-z0-9_-]+)["']?/i) ??
@@ -268,7 +328,9 @@ export function formatAssistantErrorText(
sessionKey: opts?.sessionKey,
toolName: unknownTool[1],
});
if (rewritten) return rewritten;
if (rewritten) {
return rewritten;
}
}
if (isContextOverflowError(raw)) {
@@ -311,10 +373,14 @@ export function formatAssistantErrorText(
}
export function sanitizeUserFacingText(text: string): string {
if (!text) return text;
if (!text) {
return text;
}
const stripped = stripFinalTagsFromText(text);
const trimmed = stripped.trim();
if (!trimmed) return stripped;
if (!trimmed) {
return stripped;
}
if (/incorrect role information|roles must alternate/i.test(trimmed)) {
return (
@@ -348,7 +414,9 @@ export function sanitizeUserFacingText(text: string): string {
}
export function isRateLimitAssistantError(msg: AssistantMessage | undefined): boolean {
if (!msg || msg.stopReason !== "error") return false;
if (!msg || msg.stopReason !== "error") {
return false;
}
return isRateLimitErrorMessage(msg.errorMessage ?? "");
}
@@ -404,7 +472,9 @@ const IMAGE_DIMENSION_PATH_RE = /messages\.(\d+)\.content\.(\d+)\.image/i;
const IMAGE_SIZE_ERROR_RE = /image exceeds\s*(\d+(?:\.\d+)?)\s*mb/i;
function matchesErrorPatterns(raw: string, patterns: readonly ErrorPattern[]): boolean {
if (!raw) return false;
if (!raw) {
return false;
}
const value = raw.toLowerCase();
return patterns.some((pattern) =>
pattern instanceof RegExp ? pattern.test(value) : value.includes(pattern),
@@ -421,8 +491,12 @@ export function isTimeoutErrorMessage(raw: string): boolean {
export function isBillingErrorMessage(raw: string): boolean {
const value = raw.toLowerCase();
if (!value) return false;
if (matchesErrorPatterns(value, ERROR_PATTERNS.billing)) return true;
if (!value) {
return false;
}
if (matchesErrorPatterns(value, ERROR_PATTERNS.billing)) {
return true;
}
return (
value.includes("billing") &&
(value.includes("upgrade") ||
@@ -433,7 +507,9 @@ export function isBillingErrorMessage(raw: string): boolean {
}
export function isBillingAssistantError(msg: AssistantMessage | undefined): boolean {
if (!msg || msg.stopReason !== "error") return false;
if (!msg || msg.stopReason !== "error") {
return false;
}
return isBillingErrorMessage(msg.errorMessage ?? "");
}
@@ -451,9 +527,13 @@ export function parseImageDimensionError(raw: string): {
contentIndex?: number;
raw: string;
} | null {
if (!raw) return null;
if (!raw) {
return null;
}
const lower = raw.toLowerCase();
if (!lower.includes("image dimensions exceed max allowed size")) return null;
if (!lower.includes("image dimensions exceed max allowed size")) {
return null;
}
const limitMatch = raw.match(IMAGE_DIMENSION_ERROR_RE);
const pathMatch = raw.match(IMAGE_DIMENSION_PATH_RE);
return {
@@ -472,9 +552,13 @@ export function parseImageSizeError(raw: string): {
maxMb?: number;
raw: string;
} | null {
if (!raw) return null;
if (!raw) {
return null;
}
const lower = raw.toLowerCase();
if (!lower.includes("image exceeds") || !lower.includes("mb")) return null;
if (!lower.includes("image exceeds") || !lower.includes("mb")) {
return null;
}
const match = raw.match(IMAGE_SIZE_ERROR_RE);
return {
maxMb: match?.[1] ? Number.parseFloat(match[1]) : undefined,
@@ -483,7 +567,9 @@ export function parseImageSizeError(raw: string): {
}
export function isImageSizeError(errorMessage?: string): boolean {
if (!errorMessage) return false;
if (!errorMessage) {
return false;
}
return Boolean(parseImageSizeError(errorMessage));
}
@@ -492,19 +578,37 @@ export function isCloudCodeAssistFormatError(raw: string): boolean {
}
export function isAuthAssistantError(msg: AssistantMessage | undefined): boolean {
if (!msg || msg.stopReason !== "error") return false;
if (!msg || msg.stopReason !== "error") {
return false;
}
return isAuthErrorMessage(msg.errorMessage ?? "");
}
export function classifyFailoverReason(raw: string): FailoverReason | null {
if (isImageDimensionErrorMessage(raw)) return null;
if (isImageSizeError(raw)) return null;
if (isRateLimitErrorMessage(raw)) return "rate_limit";
if (isOverloadedErrorMessage(raw)) return "rate_limit";
if (isCloudCodeAssistFormatError(raw)) return "format";
if (isBillingErrorMessage(raw)) return "billing";
if (isTimeoutErrorMessage(raw)) return "timeout";
if (isAuthErrorMessage(raw)) return "auth";
if (isImageDimensionErrorMessage(raw)) {
return null;
}
if (isImageSizeError(raw)) {
return null;
}
if (isRateLimitErrorMessage(raw)) {
return "rate_limit";
}
if (isOverloadedErrorMessage(raw)) {
return "rate_limit";
}
if (isCloudCodeAssistFormatError(raw)) {
return "format";
}
if (isBillingErrorMessage(raw)) {
return "billing";
}
if (isTimeoutErrorMessage(raw)) {
return "timeout";
}
if (isAuthErrorMessage(raw)) {
return "auth";
}
return null;
}
@@ -513,6 +617,8 @@ export function isFailoverErrorMessage(raw: string): boolean {
}
export function isFailoverAssistantError(msg: AssistantMessage | undefined): boolean {
if (!msg || msg.stopReason !== "error") return false;
if (!msg || msg.stopReason !== "error") {
return false;
}
return isFailoverErrorMessage(msg.errorMessage ?? "");
}