File size: 4,954 Bytes
6aae67a cd92039 6aae67a cd92039 6aae67a cd92039 6aae67a cd92039 6aae67a cd92039 6aae67a cd92039 6aae67a |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
/** @format */
const ClientLLM = (apiKey) => {
let abortController = null;
let isCancelled = false;
const createResult = (ok, response = null, error = null) => {
return {
ok,
response,
error,
};
};
const createError = (message, type, code, details) => ({
message: message || null,
type: type || null,
code: code || null,
details: {
message: details?.message || null,
type: details?.type || null,
param: details?.param || null,
code: details?.code || null,
},
});
const handleHttpError = async (response) => {
const errorMessages = {
400: "Richiesta non valida",
401: "Non autorizzato - Controlla la API key",
403: "Accesso negato",
404: "Endpoint non trovato",
429: "Troppe richieste - Rate limit superato",
500: "Errore interno del server",
503: "Servizio non disponibile",
};
let detailsContent;
let errorType = "HTTPError";
let message = errorMessages[response.status] || `Errore HTTP ${response.status}`;
try {
if (response.headers.get("Content-Type")?.includes("application/json")) {
detailsContent = await response.json();
if (response.status === 400 && detailsContent) {
const errorMsg = typeof detailsContent.error === "string" ? detailsContent.error : detailsContent.message || detailsContent.error?.message;
if (
errorMsg &&
(errorMsg.includes("token limit") || errorMsg.includes("token exceeded") || errorMsg.includes("input too long") || errorMsg.includes("context length") || errorMsg.includes("max tokens"))
) {
message = "Input troppo lungo - Superato il limite di token";
errorType = "TokenLimitError";
}
}
} else {
detailsContent = await response.text();
if (response.status === 400 && (detailsContent.includes("token limit") || detailsContent.includes("input too long") || detailsContent.includes("context length"))) {
message = "Input troppo lungo - Superato il limite di token";
errorType = "TokenLimitError";
}
}
} catch (e) {
detailsContent = { message: "Impossibile estrarre i dettagli dell'errore" };
}
return createError(message, errorType, response.status, typeof detailsContent === "string" ? { message: detailsContent } : detailsContent);
};
const handleNetworkError = (error) => {
if (error.name === "AbortError") {
if (isCancelled) {
return createError("Richiesta annullata dall'utente", "CancellationError", 499, { message: "La richiesta è stata interrotta volontariamente dall'utente" });
} else {
return createError("Richiesta interrotta per timeout", "TimeoutError", 408, { message: "La richiesta è stata interrotta a causa di un timeout", isTimeout: true });
}
}
if (error.name === "TypeError" && error.message.includes("Failed to fetch")) {
return createError("Errore di rete", "NetworkError", 0, { message: "Impossibile raggiungere il server. Controlla la connessione." });
}
return createError("Errore imprevisto", error.name || "UnknownError", 500, { message: error.message || "Si è verificato un errore sconosciuto" });
};
const sendRequest = async (url, payload, requestTimeout = 60) => {
isCancelled = false;
abortController = new AbortController();
const actualTimeoutMs = requestTimeout * 1000;
const timeoutId = setTimeout(() => {
if (abortController) {
abortController.abort();
}
}, actualTimeoutMs);
try {
const response = await fetch(url, {
method: "POST",
headers: {
Authorization: `Bearer ${apiKey}`,
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
signal: abortController.signal,
});
if (isCancelled) {
const cancelledError = createError("Richiesta annullata", "CancellationError", 499, { message: "La richiesta è stata interrotta volontariamente dall'utente" });
return createResult(false, null, cancelledError);
}
if (!response.ok) {
console.error("error ok=false\n", response);
const err = await handleHttpError(response);
return createResult(false, null, err);
}
const respJson = await response.json();
return createResult(true, respJson, null);
} catch (error) {
const err = handleNetworkError(error);
console.error("error network:\n", error);
return createResult(false, null, err);
} finally {
clearTimeout(timeoutId);
abortController = null;
}
};
const cancelRequest = () => {
isCancelled = true;
if (abortController) {
abortController.abort();
abortController = null;
return true;
}
return false;
};
return {
sendRequest,
createError,
cancelRequest,
};
};
|