Mithril — это лёгкий и производительный фреймворк для построения SPA
на JavaScript, который включает собственный модуль для работы с
HTTP-запросами через m.request. Корректная обработка
сетевых ошибок является важной частью любой надёжной веб-приложения, так
как позволяет реагировать на непредвиденные ситуации и поддерживать
устойчивость интерфейса.
m.requestm.request предоставляет обёртку над стандартным
fetch, но с более удобным синтаксисом и встроенной
поддержкой промисов. Его базовый вызов выглядит так:
m.request({
method: "GET",
url: "/api/data",
})
.then(response => {
console.log(response);
})
.catch(error => {
console.error(error);
});
Ключевые моменты:
method — HTTP-метод (GET,
POST, PUT, DELETE).url — адрес запроса.data — объект данных для отправки на сервер.headers — заголовки запроса.m.request автоматически отклоняет промис при сетевых
ошибках, таких как невозможность соединения. Однако HTTP-статусы вроде
404 или 500 не всегда вызывают исключение, если не
настроено явное преобразование. Для контроля таких ситуаций используется
опция unwrapSuccess и обработка в .then:
m.request({
method: "GET",
url: "/api/data",
unwrapSuccess: false
})
.then(response => {
if (response.status >= 400) {
throw new Error(`Ошибка сервера: ${response.status}`);
}
return response.data;
})
.catch(error => {
console.error("Произошла ошибка запроса:", error.message);
});
unwrapSuccess: false заставляет m.request
возвращать весь объект ответа, включая статус.response.status позволяет самостоятельно
реагировать на ошибки.try/catch с async/awaitДля более современного синтаксиса и улучшенной читаемости кода
применяют async/await:
async function fetchData() {
try {
const response = await m.request({
method: "GET",
url: "/api/data",
});
console.log(response);
} catch (error) {
console.error("Ошибка сети или сервера:", error);
}
}
Особенности:
m.request перехватываются блоком
catch.async/await — линейный поток кода, более
удобный для сложных цепочек запросов.В некоторых случаях требуется различать типы ошибок: сетевые
проблемы, ошибки сервера и ошибки данных. Для этого
m.request предоставляет объект ошибки с полями
code, status и message:
m.request({
method: "GET",
url: "/api/data",
})
.catch(err => {
if (err.code === 0) {
console.error("Сетевая ошибка: сервер недоступен");
} else if (err.status >= 500) {
console.error("Ошибка сервера:", err.message);
} else {
console.error("Неизвестная ошибка:", err);
}
});
err.code === 0 указывает на отсутствие соединения или
таймаут.err.status содержит HTTP-статус ответа сервера.err.message описывает проблему.Mithril позволяет добавлять таймауты к запросам через
timeout:
m.request({
method: "GET",
url: "/api/data",
timeout: 5000
})
.catch(err => {
console.error("Запрос не выполнен за 5 секунд:", err);
});
Для критичных данных часто реализуют механизм повторных попыток:
async function fetchWithRetry(url, retries = 3) {
for (let i = 0; i < retries; i++) {
try {
const response = await m.request({ method: "GET", url });
return response;
} catch (error) {
if (i === retries - 1) throw error;
}
}
}
В крупных приложениях удобно создавать отдельный модуль для работы с HTTP, где реализованы:
Пример структуры:
export async function apiRequest(options) {
try {
return await m.request(options);
} catch (err) {
handleError(err);
throw err;
}
}
function handleError(err) {
if (err.code === 0) alert("Нет соединения с сервером");
else if (err.status >= 500) console.error("Серверная ошибка:", err.message);
else console.warn("Ошибка запроса:", err);
}
Такой подход упрощает поддержку приложения и снижает дублирование кода.
При множественных одновременных запросах полезно использовать
Promise.allSettled для получения информации о каждом
результате:
const requests = [
m.request({ method: "GET", url: "/api/user" }),
m.request({ method: "GET", url: "/api/orders" })
];
Promise.allSettled(requests)
.then(results => {
results.forEach(result => {
if (result.status === "fulfilled") {
console.log("Успешно:", result.value);
} else {
console.error("Ошибка запроса:", result.reason);
}
});
});
fulfilled — успешный ответ.rejected — ошибка запроса.Обработка ошибок сети в Mithril требует понимания механизма промисов
и особенностей m.request. Использование catch,
async/await, таймаутов, повторных попыток и
централизованных обработчиков обеспечивает устойчивость приложения и
корректное взаимодействие с пользователем даже при сбоях соединения или
ошибках сервера.