umay-render
Version:
Free, high-performance HTML to PDF and HTML to Image conversion SDK for both browser and Node.js
212 lines (211 loc) • 11.1 kB
JavaScript
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.HttpClient = void 0;
// src/http-client.ts
const axios_1 = __importDefault(require("axios"));
const errors_1 = require("./errors"); // ErrorCodes import edildi
// ensureUint8Array fonksiyonu aynı kalır...
function ensureUint8Array(data) {
if (data instanceof Uint8Array)
return data;
if (data instanceof ArrayBuffer)
return new Uint8Array(data);
if (typeof data === "object" &&
data !== null &&
typeof data.byteLength === "number") {
try {
return new Uint8Array(data);
}
catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error);
throw new Error(`Cannot convert to Uint8Array: ${errorMessage}`);
}
}
throw new Error(`Cannot convert to Uint8Array: Unsupported data type ${typeof data}`);
}
class HttpClient {
constructor(config) {
this.config = config;
this.client = axios_1.default.create({
baseURL: config.API_URL,
timeout: config.TIMEOUT,
headers: {
"Content-Type": "application/json",
Accept: "application/json, image/*, application/pdf", // Accept başlığını doğru ayarla
},
responseType: "arraybuffer",
validateStatus: (status) => status < 500, // Sadece 5xx hataları AxiosError olarak fırlat
});
}
async request(endpoint, data) {
try {
// İstek loglaması (opsiyonel)
// console.log(`Making POST ${endpoint} request with data:`, JSON.stringify(data));
// Axios isteği
const response = await this.client.post(endpoint, data, {
// responseType: 'arraybuffer' zaten instance seviyesinde ayarlı
// headers Accept de instance seviyesinde ayarlı
});
// Başarılı yanıt işleme (2xx)
// console.log(`Received response from ${endpoint}: Status ${response.status}`);
return this.processSuccessResponse(response);
}
catch (error) {
// --- Hata İşleme ---
console.error(`HTTP client error during request to ${endpoint}:`, error);
// Axios Hatası mı? (Genellikle 5xx veya ağ/timeout hataları)
if (axios_1.default.isAxiosError(error)) {
const axiosError = error; // Tip belirlemesi
// Timeout hatası mı?
if (axiosError.code === "ECONNABORTED" ||
axiosError.message.includes("timeout")) {
throw new errors_1.UmayError(errors_1.ErrorCodes.TIMEOUT, // Timeout kodu
`Request timed out after ${this.config.TIMEOUT}ms`, axiosError.config // İlgili isteğin konfigürasyonunu detay olarak ekle
);
}
// Yanıt alındı mı? (Genellikle 5xx)
if (axiosError.response) {
// 5xx yanıtlarını işle (processResponse 4xx'leri işlemişti ama validateStatus ile bu değişti)
return this.processErrorResponse(axiosError.response);
}
else if (axiosError.request) {
// İstek yapıldı ama yanıt alınamadı (Ağ hatası)
throw new errors_1.UmayError(errors_1.ErrorCodes.NETWORK_ERROR, `Network error: No response received from server. ${axiosError.message}`, { requestDetails: axiosError.request });
}
else {
// İstek ayarlanırken hata oluştu
throw new errors_1.UmayError(errors_1.ErrorCodes.NETWORK_ERROR, // Veya daha spesifik bir kod?
`Request setup error: ${axiosError.message}`, axiosError.config);
}
}
// Axios olmayan beklenmedik hata
throw new errors_1.UmayError(errors_1.ErrorCodes.NETWORK_ERROR, // Genel ağ/bilinmeyen hata kodu
error instanceof Error
? error.message
: "Unknown network or client error", error // Orijinal hatayı detay olarak sakla
);
}
}
/** Başarılı (2xx) yanıtları işler */
processSuccessResponse(response) {
const contentType = response.headers["content-type"]?.toLowerCase() || "";
const data = response.data;
// Binary veri (PDF veya görseller)
if (contentType.includes("application/pdf") ||
contentType.includes("image/")) {
try {
const uint8Array = ensureUint8Array(data);
// console.log(`Processed binary response (${contentType}): ${uint8Array.length} bytes`);
return uint8Array; // T'nin Uint8Array olacağını varsayıyoruz
}
catch (e) {
console.error("Failed to process binary data:", e);
// Bu durumda ne yapılmalı? Hata fırlatmak daha iyi olabilir.
throw new errors_1.UmayError(errors_1.ErrorCodes.API_ERROR, "Failed to process binary response from API", e);
}
}
// Diğer içerik tipleri (JSON beklenmiyor ama olabilir)
if (contentType.includes("application/json")) {
try {
const text = new TextDecoder().decode(data);
const jsonData = JSON.parse(text);
// console.log("Processed JSON response:", jsonData);
return jsonData; // T'nin JSON nesnesi olacağını varsayıyoruz
}
catch (e) {
console.warn("Received JSON content-type but failed to parse response body.");
// Belki de boş yanıt? Ya da text olarak dönelim?
// Ya da hata fırlatmak daha güvenli.
throw new errors_1.UmayError(errors_1.ErrorCodes.API_ERROR, "Failed to parse JSON response from API", { responseText: new TextDecoder().decode(data) });
}
}
// Beklenmedik içerik tipi veya boş yanıt
console.warn(`Unexpected content type received: ${contentType}. Returning raw data.`);
try {
// Yine de Uint8Array'e çevirmeyi deneyelim, belki istemci işleyebilir
const uint8Array = ensureUint8Array(data);
return uint8Array;
}
catch (e) {
// Başarısız olursa, ham veriyi dön (pek olası değil arraybuffer için)
return data;
}
}
/** Hatalı (4xx, 5xx) API yanıtlarını işler ve UmayError fırlatır */
processErrorResponse(response) {
// Bu metodun aslında T dönmemesi, hata fırlatması lazım
const status = response.status;
let errorCode = errors_1.ErrorCodes.API_ERROR; // Varsayılan kod
let errorMessage = `API request failed with status ${status}`;
let errorDetails = null;
let publicMessage = undefined; // Opsiyonel kullanıcı dostu mesaj
try {
if (response.data && response.data.byteLength > 0) {
const text = new TextDecoder().decode(response.data);
// console.log("Raw error response text:", text); // Hata ayıklama için
try {
const json = JSON.parse(text);
// Backend'in hata yapısını varsayıyoruz: { error: { code: 'CODE', message: 'InternalMsg', publicMessage?: 'UserMsg' }, details?: any }
// Veya { error: { code: 'CODE', message: 'PublicMsg', internal_message?: 'InternalMsg'}, ... } (errorHandler'a göre)
// Backend'deki errorHandler yapısına göre ayarla:
if (json.error && typeof json.error === "object") {
const errObj = json.error;
// --- Backend kodunu al ---
const backendCode = errObj.code;
if (backendCode && typeof backendCode === "string") {
// Backend kodunu ErrorCodes içinde ara, varsa kullan, yoksa string olarak kullan
errorCode = Object.prototype.hasOwnProperty.call(errors_1.ErrorCodes, backendCode)
? backendCode
: backendCode;
}
// --- Mesajları al ---
// Public message varsa önceliklendir
publicMessage =
typeof errObj.message === "string" ? errObj.message : undefined; // Hata mesajını public varsayalım
// Internal message varsa geliştirici mesajı olarak kullan
errorMessage =
typeof errObj.internal_message === "string"
? errObj.internal_message
: publicMessage || errorMessage; // İç mesaj yoksa dış mesajı kullan
}
else if (typeof json.error === "string") {
// Eski yapı: { error: "Mesaj", details?: ... }
publicMessage = json.error; // Ana mesajı public varsayalım
errorMessage = json.error;
}
// Detayları al
errorDetails = json.details || json.stack || json; // Stack veya tüm JSON detay olabilir
}
catch (parseError) {
// JSON değilse, yanıtı text olarak kullan
console.warn("API error response was not valid JSON:", text);
errorMessage = `API Error (${status}): ${text || "No response body"}`;
publicMessage = `An API error occurred (Status: ${status})`; // Genel mesaj
errorDetails = { responseText: text };
}
}
else {
// Boş yanıt gövdesi
errorMessage = `API request failed with status ${status} and empty response body`;
publicMessage = `An API error occurred (Status: ${status})`; // Genel mesaj
}
}
catch (decodeError) {
console.error("Error processing API error response data:", decodeError);
errorMessage = `Failed to process error response (Status: ${status})`;
publicMessage = `An error occurred while processing the API response (Status: ${status})`;
errorDetails = decodeError;
}
// Hata fırlat, bu metodun bir değer dönmemesi gerekiyor.
throw new errors_1.UmayError(errorCode, errorMessage, {
// `details` içine publicMessage'ı da ekleyebiliriz
status: status,
responseDetails: errorDetails,
publicMessage: publicMessage, // İstemci bu public mesajı kullanabilir
});
}
}
exports.HttpClient = HttpClient;
;