Mã lỗi & Xử lý sự cố
Bảng tổng hợp mã trạng thái HTTP, chi tiết mã lỗi error_code, định dạng phản hồi chuẩn và cẩm nang xử lý sự cố khi tích hợp Bvoiz API.
1. Cấu trúc phản hồi lỗi chuẩn (Standard Error Response)
Tất cả các endpoint của Bvoiz REST API đều trả về định dạng JSON thống nhất khi xảy ra lỗi. Khi yêu cầu thất bại, trường status sẽ luôn mang giá trị 0, đi kèm mã lỗi định danh error_code và thông điệp giải thích cụ thể:
{
"status": 0,
"error_code": "INSUFFICIENT_CREDITS",
"error_message": "Tài khoản không đủ credits để thực hiện chuyển đổi",
"details": "Yêu cầu cần 1.250 credits nhưng số dư hiện tại chỉ còn 320 credits. Vui lòng nạp thêm."
}| Trường dữ liệu | Kiểu | Mô tả |
|---|---|---|
| status | Number | Luôn là 0 biểu thị yêu cầu thất bại (ngược lại 1 là thành công). |
| error_code | String | Mã chuỗi chuẩn hóa dạng SCREAMING_SNAKE_CASE dùng để lập trình viên bắt lỗi logic tự động. |
| error_message | String | Mô tả lỗi bằng tiếng Việt tự nhiên, phù hợp để hiển thị trực tiếp cho người dùng cuối. |
| details | String (tùy chọn) | Thông tin chi tiết kỹ thuật bổ sung (số credits còn thiếu, vị trí tham số sai định dạng,...). |
2. Bảng mã trạng thái HTTP (HTTP Status Codes)
Bvoiz tuân thủ chuẩn HTTP/1.1 RESTful conventions. Bạn nên kiểm tra mã HTTP status code trước, sau đó phân tích trường error_code trong JSON payload:
| HTTP Code | Ý nghĩa | Mô tả ngữ cảnh | Khuyến nghị khắc phục |
|---|---|---|---|
| 200 OK | Thành công | Yêu cầu được thực thi trọn vẹn, dữ liệu âm thanh hoặc đơn hàng đã sẵn sàng. | Đọc kết quả từ thuộc tính result. |
| 400 Bad Request | Dữ liệu không hợp lệ | Thiếu tham số bắt buộc, văn bản rỗng, vượt quá độ dài ký tự hoặc tài khoản không đủ credits. | Kiểm tra lại body request, số dư tài khoản hoặc độ dài đoạn văn bản. |
| 401 Unauthorized | Chưa xác thực | Thiếu header Authorization: Bearer, API Key sai hoặc đã hết hiệu lực. | Kiểm tra API Key trong trang quản lý tài khoản Bvoiz. |
| 403 Forbidden | Bị từ chối truy cập | Gói cước hiện tại không hỗ trợ tính năng này (ví dụ: gói Free gọi API nhân bản giọng nói). | Nâng cấp lên gói cước hỗ trợ tương ứng (Basic, Advanced hoặc Premium). |
| 429 Too Many Requests | Vượt hạn mức tần suất | Gửi quá nhiều yêu cầu trong 1 phút (mặc định giới hạn 10 requests/phút đối với gói thông thường). | Áp dụng thuật toán Exponential Backoff hoặc nâng cấp gói để mở rộng quota. |
| 500 Server Error | Lỗi máy chủ nội bộ | Hệ thống xử lý tổng hợp âm thanh gặp trục trặc tạm thời hoặc dịch vụ lưu trữ R2 bị gián đoạn. | Thử lại sau 2-5 giây hoặc liên hệ hỗ trợ kỹ thuật Bvoiz. |
3. Bảng mã lỗi nghiệp vụ chi tiết (Error Code Reference)
Bảng kê các mã error_code thường gặp trong hệ sinh thái API của Bvoiz cùng nguyên nhân và giải pháp tương ứng:
| Mã lỗi (error_code) | HTTP Code | Ý nghĩa & Nguyên nhân | Cách xử lý |
|---|---|---|---|
| INSUFFICIENT_CREDITS | 400 | Số dư credits của tài khoản không đủ để thanh toán cho số ký tự của văn bản gửi lên. | Mua thêm gói credits tại Bảng giá. |
| RATE_LIMITED | 429 | Vượt quá hạn mức tần suất gửi request cho phép trong cửa sổ thời gian 1 phút. | Giảm tốc độ gọi API hoặc cài đặt hàm retry có thời gian chờ ngẫu nhiên. |
| UNAUTHORIZED | 401 | Yêu cầu chưa được xác thực hoặc tiêu đề Authorization bị bỏ trống. | Thêm Header: Authorization: Bearer <API_KEY>. |
| INVALID_TOKEN | 401 | Khóa bí mật API Key không chính xác, đã bị vô hiệu hóa hoặc thu hồi. | Tạo API Key mới trong màn hình Quản lý tài khoản > Tích hợp API. |
| EMPTY_INPUT_TEXT | 400 | Trường text trong body bị để trống, chuỗi rỗng hoặc chỉ chứa khoảng trắng. | Kiểm tra dữ liệu đầu vào trước khi gửi request. |
| TEXT_TOO_LONG | 400 | Số lượng ký tự văn bản vượt quá hạn mức tối đa một lần chuyển đổi của gói cước. | Chia nhỏ văn bản thành các đoạn ngắn hơn hoặc nâng cấp gói cước cao hơn. |
| VOICE_NOT_FOUND | 400 | Mã định danh giọng đọc speaker_id không tồn tại trong danh mục hệ thống. | Gọi endpoint GET /api/tts/voices để lấy danh sách speaker_id hợp lệ. |
| FORBIDDEN | 403 | Tài khoản bị khóa tạm thời hoặc không đủ quyền truy cập tài nguyên requested. | Liên hệ ban quản trị qua email [email protected] để được giải quyết. |
| ORDER_NOT_FOUND | 404 | Mã đơn hàng chuyển khoản (order_code) không tồn tại trong cơ sở dữ liệu. | Kiểm tra lại mã đơn hàng (định dạng chuẩn BVOIZ xxxxxx). |
| ORDER_ALREADY_PAID | 400 | Đơn hàng đã được thanh toán và kích hoạt thành công từ trước. | Không cần thanh toán lại, kiểm tra số dư credits trong tài khoản. |
| SYNTHESIS_FAILED | 500 | Lỗi tiến trình render file âm thanh từ mô hình AI (do lỗi ký tự đặc biệt lạ, v.v.). | Loại bỏ các ký tự điều khiển lạ hoặc thử lại với giọng đọc khác. |
| INTERNAL_SERVER_ERROR | 500 | Lỗi không mong muốn phát sinh từ hệ thống máy chủ Bvoiz. | Thử lại sau ít phút hoặc tra cứu kênh trạng thái hệ thống. |
4. Cẩm nang xử lý sự cố thường gặp (Troubleshooting Guide)
Sự cố 1: Lỗi 401 Unauthorized khi gọi API
Nguyên nhân chủ yếu do chưa đính kèm tiêu đề HTTP Authorization hoặc quên từ khóa Bearer phía trước key. Cú pháp chính xác là:
Sự cố 2: Lỗi 429 Rate Limited & Chiến thuật Exponential Backoff
Khi chạy các batch job lớn (ví dụ chuyển đổi 100 chương sách), không nên dùng vòng lặp Promise.all() gửi đồng thời toàn bộ. Hãy phân chia batch nhỏ (3-5 request/lần) và cài đặt khoảng nghỉ giữa các lần gọi (Delay). Khi gặp 429, hãy chờ thời gian gấp đôi sau mỗi lần thử kèm biến thiên ngẫu nhiên (Jitter) để tránh bão request lặp lại.
Sự cố 3: Đột ngột gặp lỗi INSUFFICIENT_CREDITS
Số credits trong tài khoản được trừ theo thời gian thực (1 ký tự = 1 credit). Khi số dư không đủ thanh toán cho toàn bộ kịch bản, hệ thống sẽ từ chối tạo audio và không trừ bất kỳ credit nào. Bạn có thể kiểm tra số dư hiện tại bất kỳ lúc nào qua endpoint GET /api/auth/me trước khi gửi yêu cầu chuyển đổi.
Sự cố 4: Timeout kết nối khi tổng hợp văn bản rất dài
Với các đoạn văn bản trên 10.000 ký tự, thời gian xử lý AI có thể kéo dài từ 5-15 giây. Hãy tăng thời gian timeout của HTTP client lên ít nhất 30 giây (hoặc 60 giây). Ngoài ra, bạn có thể sử dụng endpoint truy vấn lịch sử GET /api/tts/history để lấy lại liên kết tải file âm thanh đã hoàn tất.
5. Ví dụ code bắt & xử lý lỗi hoàn chỉnh
Dưới đây là đoạn mã hoàn chỉnh minh họa cách bắt mã lỗi, áp dụng Exponential Backoff tự động khi gặp 429 và thông báo chi tiết cho người dùng:
import fetch from "node-fetch";
interface ApiResponse<T> {
status: number;
result?: T;
error_code?: string;
error_message?: string;
details?: string;
}
async function synthesizeText(text: string, speakerId: string, apiKey: string) {
const maxRetries = 3;
let delay = 1000; // 1 giây
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
const response = await fetch("https://api.bvoiz.com/api/tts/synthesize", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${apiKey}`,
},
body: JSON.stringify({
text,
speaker_id: speakerId,
audio_type: "mp3",
}),
});
const data = (await response.json()) as ApiResponse<any>;
// Xử lý mã trạng thái HTTP 200 OK
if (response.ok && data.status === 1) {
return data.result;
}
// Xử lý các mã lỗi nghiệp vụ
switch (data.error_code) {
case "INSUFFICIENT_CREDITS":
console.error("Lỗi số dư:", data.error_message);
throw new Error("Vui lòng nạp thêm credits tại https://bvoiz.com/pricing");
case "RATE_LIMITED":
if (attempt < maxRetries) {
const jitter = Math.random() * 500;
console.warn(`Bị giới hạn tần suất. Đang thử lại lần ${attempt} sau ${delay + jitter}ms...`);
await new Promise((resolve) => setTimeout(resolve, delay + jitter));
delay *= 2; // Tăng thời gian chờ theo hàm mũ
continue;
}
break;
case "UNAUTHORIZED":
case "INVALID_TOKEN":
throw new Error("API Key không hợp lệ. Vui lòng kiểm tra lại cấu hình BVOIZ_API_KEY.");
default:
throw new Error(`[${data.error_code || response.status}] ${data.error_message || "Lỗi không xác định"}`);
}
} catch (err: any) {
if (attempt === maxRetries) throw err;
}
}
}