Backbone.js строит взаимодействие с сервером вокруг моделей
(Backbone.Model), коллекций
(Backbone.Collection) и метода Backbone.sync,
который по умолчанию использует jQuery.ajax. Сетевые ошибки
возникают на нескольких уровнях:
Корректная обработка требует понимания, на каком этапе произошёл сбой, и как Backbone передаёт информацию об ошибке.
Backbone.sync и распространение ошибокВсе операции fetch, save,
destroy в конечном итоге вызывают
Backbone.sync(method, model, options). Если сервер
возвращает ошибку, Backbone:
options.error;error у модели или коллекции.Сигнатура error-обработчика:
error: function(model, xhr, options) {
// model — модель или коллекция
// xhr — jqXHR-объект
// options — объект параметров
}
Ключевые данные содержатся в xhr:
xhr.status — HTTP-код;xhr.responseText — текст ответа;xhr.responseJSON — распарсенный JSON (если
доступен).fetchfetch используется для загрузки данных с сервера и
особенно чувствителен к сетевым сбоям.
model.fetch({
success: function(model, response) {
// данные успешно загружены
},
error: function(model, xhr) {
if (xhr.status === 404) {
// ресурс не найден
}
}
});
При ошибке:
sync не вызывается;error.Дополнительно можно подписаться на событие:
model.on('error', function(model, xhr) {
// централизованная реакция
});
savesave может выполняться как POST,
PUT или PATCH. Ошибки здесь критичны, так как
связаны с сохранением состояния.
model.save(data, {
wait: true,
error: function(model, xhr) {
// сервер отклонил сохранение
}
});
Параметр wait: true Если не указан,
Backbone оптимистично обновляет модель до ответа сервера. При сетевой
ошибке состояние уже будет изменено, что усложняет откат.
С wait: true:
Часто API возвращает HTTP 200, но сообщает об ошибке в JSON:
{
"error": "Validation failed",
"fields": {
"email": "invalid"
}
}
Backbone не считает такой ответ ошибкой автоматически. Необходима
ручная проверка в success:
success: function(model, response) {
if (response.error) {
model.trigger('error', model, response);
return;
}
}
Для системной обработки логических ошибок этот подход неудобен. Более
правильное решение — использовать validate.
validate для сетевых ошибокМетод validate(attrs, options) вызывается перед
сохранением, но может применяться и для анализа серверного ответа:
validate: function(attrs, options) {
if (options.serverError) {
return options.serverError;
}
}
В error-callback:
error: function(model, xhr) {
var response = xhr.responseJSON;
model.save(null, {
serverError: response
});
}
Если validate возвращает значение, Backbone:
invalid.Backbone.syncДля крупных приложений локальная обработка быстро приводит к дублированию кода. Backbone допускает глобальное переопределение:
var originalSync = Backbone.sync;
Backbone.sync = function(method, model, options) {
var error = options.error;
options.error = function(xhr) {
if (xhr.status === 401) {
// неавторизован
}
if (error) error.apply(this, arguments);
};
return originalSync.call(this, method, model, options);
};
Преимущества:
По умолчанию jQuery.ajax не задаёт таймаут. Его можно
определить в sync или в конкретном запросе:
model.fetch({
timeout: 5000,
error: function(model, xhr) {
if (xhr.status === 0) {
// вероятный таймаут или отсутствие сети
}
}
});
Реализация повторных попыток:
function fetchWithRetry(model, retries) {
model.fetch({
error: function() {
if (retries > 0) {
fetchWithRetry(model, retries - 1);
}
}
});
}
Коллекции обрабатывают ошибки аналогично моделям, но важно учитывать, что ошибка может относиться ко всему набору данных.
collection.fetch({
error: function(collection, xhr) {
// коллекция осталась в прежнем состоянии
}
});
Событие:
collection.on('error', function(collection, xhr) {
// обработка
});
При частичном успехе (сервер вернул неполный список) Backbone не предоставляет встроенных механизмов различения — ответственность лежит на API.
Метод parse(response, options) вызывается при успешном
HTTP-ответе. Если внутри parse происходит ошибка (например,
неожиданная структура данных), это не считается сетевой ошибкой, но
может привести к неконсистентному состоянию.
Рекомендуется явно проверять формат:
parse: function(response) {
if (!Array.isArray(response.items)) {
throw new Error('Invalid response format');
}
return response.items;
}
Такие ошибки лучше перехватывать на уровне sync или
глобального обработчика исключений.
Практика показывает необходимость различать:
Типовая схема:
error, invalid) → слой
представлений.Backbone предоставляет минимальный каркас, но не навязывает архитектуру, что позволяет встроить обработку ошибок в существующую систему состояний приложения.
options.error и событие error — основные
точки входа.wait: true критичен для корректной работы при
сбоях.Backbone.sync позволяет реализовать
глобальную стратегию.Такой подход обеспечивает предсказуемое поведение приложения при нестабильной сети и упрощает сопровождение кода в долгосрочной перспективе.