2014-09-08 2 views
6

Официальный restangular документации provides этот образец кода, чтобы повторить запрос в ErrorInterceptor:Retry на Restangular вызов в перехватчика

var refreshAccesstoken = function() { 
    var deferred = $q.defer(); 

    // Refresh access-token logic 

    return deferred.promise; 
}; 

Restangular.setErrorInterceptor(function(response, deferred, responseHandler) { 
    if(response.status === 403) { 
     refreshAccesstoken().then(function() { 
      // Repeat the request and then call the handlers the usual way. 
      $http(response.config).then(responseHandler, deferred.reject); 
      // Be aware that no request interceptors are called this way. 
     }); 

     return false; // error handled 
    } 

    return true; // error not handled 
}); 

Однако, как говорится в комментариях, то вторая попытка не вызовет никаких перехватчиков потому что он напрямую использует $ http.

Есть ли способ сделать второй запрос также через ретрансляционный конвейер и выполнить ErrorInterceptor?

+1

вы можете заменить '$ http (response.config) .then (responseHandler, deferred.reject);' с вызовом restApi. Используйте перехватчики $ http вместо перестановочного перехватчика, даже с restangular.Я предпочитаю перехватчики $ http, потому что все обертки angilejs api, такие как restangular, используют внутри $ http под капотом ... – harishr

+1

Вопрос ** о ** переключается с '$ http' на' Restangular' в перехватчике. Не путайте «Restangular» с простым вызовом отдыха. –

ответ

4

На самом деле, запросы, сделанные с Restangular, используют обещания, которые были предназначены для разрешения только один раз. Вы не можете повторно отправить его в случае отказа.

Я не знаю, если вы хотите повторно использовать errorInterceptor или нет, но то, как работает сервис не кажется, позволяет повторно построить Restangular объект просто из response object config.

Одна вещь, которую вы можете сделать, это сохранить ссылку на ваш объект, а затем использовать его в перехватчик.

Вы должны иметь свои причины, но я должен предупредить вас это потому, что в случае выхода из строя, и если она сохранится, то вы могли бы в конечном итоге с бесконечным вызовом, так как Restangular всегда будет вызывать errorInterceptor.

я издевался до немного Plunkr для демонстрации, просто откройте вкладку сети и нажмите на кнопку, вы увидите весь запрос идет корыто там.

+0

У меня такой сценарий, как если бы я получил код ошибки около 200, когда я назвал какую-либо почтовую службу, мне нужно вызвать услугу (например, get), снова нужно вызвать ту же службу сообщений, в которой я получил код ошибки 200 –

1

Использование async.retry может соответствовать вашей проблеме.

Давайте предположим, что ваш асинхронная функция:

function apiCall(callback) { 
    Restangular.all('items').getList() 
    .then(function (res) { 
     // all is OK 
     callback(null, res); 
    }) 
    .catch(function (err) { 
     if (err.status === 403) { 
     // this one will bring async to retry apiMethod 
     return callback(err); 
     } 
     // others errors codes will not call apiMethod again 
     callback(null); 
    }); 
} 

Пример использования retry:

// async will try it 3 times 
async.retry(3, apiCall, function(err, result) { 
    // do something with the result 
}); 

async.doUntil может вас заинтересовать.

1

Слишком поздно для ответа, однако я нашел решение для этого, поэтому я собираюсь упомянуть его здесь как возможное решение.

Приведенная ниже ссылка содержит ссылку restangularizeElement.

https://github.com/mgonto/restangular/issues/1022

Я фиксируя restangular официальный пример следующим образом:

Restangular.setErrorInterceptor(function(response, deferred, responseHandler) { 
    if(response.status === 403) { 
    refreshAccesstoken().then(function() { 
     // instead of using $http, I will use restangularizeElement as follow 
     // I still have no idea how is the best method to repeat the request after restangularized it. I am repeating it with a simple get 
     var request = Restangular.restangularizeElement('', response.data, url); 
     request.get().then(function() {}); 
    }); 
    return false; // error handled 
    } 

    return true; // error not handled 
}); 

Таким образом, если повторный запрос вызывает ошибку, он будет пойман в restangular перехватчик ошибок снова.

Смежные вопросы