Java Vavr: исключение журнала при сбое

Я хочу регистрировать исключения при использовании VAVR (ранее javaslang). Ниже приведен пример фрагмента кода.

    //will get 500 as response from this url
    String sampleurl    =   "http://someurl.com";
    List<String>    myList  =   List.of(sampleurl);
    LOGGER.info("In {} with urls {}",getClass(),myList);        

    return Observable.from(myList).flatMap(url ->

            Observable.create(subscriber -> {

                Try<String> httpEntity  = HttpUtil.retrieveData(url).flatMap(httpResponse -> Try.of( () -> EntityUtils.toString(httpResponse.getEntity())));
                httpEntity
                        .andThen(subscriber::onNext)
                        .andThen(subscriber::onCompleted)
                        .onFailure(subscriber::onError);

            }));

Я пытаюсь зарегистрировать исключение в блоке onFailure (), но ничего не регистрируется. Пожалуйста, посоветуйте мне это.

С уважением, Джай


person Jai    schedule 29.03.2018    source источник
comment
Не могли бы вы подготовить SSCCE? Что компилирует, запускает и показывает проблему?   -  person Opal    schedule 30.03.2018
comment
Создайте правильный минимальный воспроизводимый пример.   -  person Zabuzard    schedule 31.03.2018


Ответы (1)


В обоих случаях удача и неудача, Вавр работает как положено. Вот простые тесты:

// prints nothing
Try.success("ok")
        .andThen(() -> {})
        .andThen(() -> {})
        .onFailure(System.out::println);

// prints "java.lang.Error: ok"
Try.failure(new Error("ok"))
        .andThen(() -> {})
        .andThen(() -> {})
        .onFailure(System.out::println);

Я вижу два возможных ответа, почему сбой не регистрируется в вашем примере:

  1. конфигурация логгера не соответствует вашим потребностям
  2. наблюдаемые не обрабатываются и Try никогда не вызывается

Заявитель: я создатель Вавра

person Daniel Dietrich    schedule 31.03.2018
comment
Привет @daniel, спасибо за ответ. Я, наконец, добился ведения журнала, но не смог захватить всю трассировку стека исключений. Пытался изменить метод onFailure, указанный в desc, чтобы вызвать метод ниже, но не смог получить полный стек. private Consumer<? super Throwable> logError(Try<String> httpEntity, Subscriber<? super String> subscriber){ LOGGER.info("Error occured {} {}",httpEntity,subscriber); return null; } Я выполняю http-вызов, и если что-то пойдет не так во время обработки ответа или если сам ответ равен 500, тогда вся трассировка стека должна быть зарегистрирована. ** Извините, если спросить глупо, новичок в vavr - person Jai; 02.04.2018
comment
Привет, @Jai, экземпляр Try захватывает нефатальное исключение, включив исходное исключение как есть. В вашем коде вы полагаетесь на toString метод Try при его регистрации. В случае сбоя toString определяется как "Failure(" + cause + ")", где cause - исключение, которое было перехвачено внутри Try. Вы можете получить доступ к исходному исключению, используя _ 8_. - person Daniel Dietrich; 02.04.2018
comment
Привет, @daniel, когда я пытаюсь использовать метод httpEntity.getCause в регистраторе, он терпит неудачу с исключением `java.lang.UnsupportedOperationException: getCause on Success в javaslang.control.Try $ Success.getCause (Try.java:698) 'I Я не очень уверен, как регистрировать трассировку стека исключения, когда служба, к которой я пытаюсь получить доступ, возвращает 500 или любое другое исключение при обработке ответа. Более того, если сервер возвращает 500, то запускается блок кода onFailure, но почему getCause завершается с ошибкой getCause of Success - person Jai; 02.04.2018
comment
Вы должны убедиться, что это сбой, позвонив if (httpEntity.isFailure()) { ... }. Но в вашем случае было бы проще использовать свободный API httpEntity.onFailure(e -> { /*do something with exception e*/ }). - person Daniel Dietrich; 03.04.2018
comment
Я попытался записать ошибку с помощью httpEntity.onFailure(e -> { LOGGER.info("Error "+e)*/ }), но ничего не регистрируется. Infact httpEntity.isFailure () возвращает false. Итак, проблема в том, что если сервер ответит 500, тогда выполняется httpEntity.onFailure, но httpEntity.isFailure возвращает false. Но в идеале ответ 500 должен рассматриваться как сбой, а httpEntity.isFailure должен возвращать истину. - person Jai; 03.04.2018
comment
Похоже, что экземпляр Try - это успешный экземпляр, который инкапсулирует действительный объект ответа http. Если это так, isFailure, конечно, вернет false, и обработчик, переданный в onFailure(), не будет выполнен. Вместо этого вам может потребоваться обработать код 500 в обработчике onSuccess(). Но, не видя полного кода (и стороннего API), я могу только догадываться. - person Daniel Dietrich; 04.04.2018