Всем привет!
Код - клиент SOAP web servica - делает колаут. Колаут взят в Трай-Кетч и если произошла ошибка при колауте, то код уходит в кетч.
Мне говорят: а если код уйдет в Кетч по причине тайм-аута у твоего колаута (не вернулся во время ответ по причине проблем со связью между серверами), ты не будешь пытаться еще раз сделать колаут?
Ок, давайте 3 раза подряд пытаться сделать колаут (без выяснения причин почему колаут не прошел).
получился такой код, посмотрите можно ли его как-то улучшить, или может делать какие паузы между вызовами.
спасибо
boolean ok;
System.CalloutException exception;for (int i =1; i>3; i++){
try {
if (test.isRunningTest()) { output = testOutput; } // эта линия только на случай теста
else { output = stub.NewItem(xx, xxx); } // это колаут, который может вызвать ошибку по тайм-ауту
ok = true;break; // прерываем цикл как только сделали колаут и не упали на нем
} catch (System.CalloutException e) {
exception = e;
ok = false;
}
} // закрываем цикл
if(!ok){
оправляем письмо счастья используя сообщение из exception;
return; // прерываем выполненние кода
}
и если дошли до этой линии, то уже работаем с результатом в output
Привет!
Как мне кажется, использовать еще ко всему и boolean ok; не очень обоснованно.
Во-первых, проверяй может лучше LoginResult или свой коннекшен по возвращаемому коду (200 и прочие), который тебе запрос вернет. ИМХО
Во-вторых. Что за мистическая цифра 3? Если тебе нужно сделать коллаут несмотря на дождь и слякоть отпрыгивай от лимитов
http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_methods_system_limits.htm
Integer countCallouts = Limits.getCallouts();
while ( countCallouts > 0){ ...
}
В-третьих. Ты обрабатываешь исключения? catch (System.CalloutException e) { exception = e; } - это обработка? А что дальше? Если это условно - то ок...а если это целостный кусок кода...то на исключение нужно как-то среагировать....
В-четвертых. try-catch-finally блок можно использовать
Вот это отличная идея. Спасибо
сейчас попробую сделать вот так:
while ( Limits.getLimitCallouts() > 0){
...колаут...
}по поводу обработки исключения - позже отпишусь в этом сообщении
PS: Limits.getLimitCallouts() > 0 - так не получается, оказывается это неизменная величина, я думал она менятся и показывает остаток возможных колаутов по ходу выполнения кода.
тогда попробую вот так:
boolean ok;
System.CalloutException myException;while ( Limits.getCallouts() < Limits.getLimitCallouts() ){
try {
if (test.isRunningTest()) { output = testOutput; } // эта линия только на случай теста
else { output = stub.NewItem(xx, xxx); } // это колаут, который может вызвать ошибку по тайм-ауту
ok = true;break; // прерываем цикл как только сделали колаут и не упали на нем
} catch (System.CalloutException e) {
myException = e;
ok = false;
}
} // закрываем цикл
if(!ok){
// обработка исключения c использованием myException
return; // прерываем выполненние кода
}
//и если дошли до этой линии, то уже работаем с результатом в output
PSS: да, вариант выше делает десять неуспешных вызовов подряд (или обрывает цикл после первого успешного).
Обработку исключения я перенес вне цикла, в секцию if(!ok), так мне не нужно обрабатывать каждую неудачную попытку, а только если все 10 неудачны.
Проблемы:
(1) не могу спровоцировать ошибку по тайм-ауту. Ставлю неверный end point (УРЛ) в вызове, но тогда получается ошибка:
Exeption message: System.CalloutException: Web service callout failed: Unexpected element... but found ':HTML'.
судя по всему провайдер ставит какую страницу-заглушку в случае несуществующего УРЛ;
(2) не получилось дебажить колаут в Эклипсе.
в Эклипсе в Execute Anonymous можно спровоцировать тригер, который который сделает ауткол с помощью футут метода, но дебажные данные асинхронного процесса не попадают в дебаг лог.
можно убрать футур аннотацию из класса и вызвать его метод прямо, но без футур аннотации не происходит сам колаут, он возвращает ошибку. В-общем, дебажу в Орге...