1

I want to log exceptions while using VAVR (formerly javaslang). Below is the sample code snippet.

    //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);

            }));

I am trying to log exception in the onFailure() block but nothing gets logged. Please advise me on this.

Regards, Jai

Jai
  • 369
  • 3
  • 16

1 Answers1

2

In both cases, success and failure, Vavr works as expected. Here are simple tests:

// 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);

I see two possible answers why the failure is not logged in your example:

  1. the logger configuration does not fit your needs
  2. the observables are not processed and Try is never called

Disclamer: I'm the creator of Vavr

Daniel Dietrich
  • 2,262
  • 20
  • 25
  • Hi @daniel, thanks for response. I finally achieved logging but unable to capture entire exception stack trace. Tried modifying _onFailure_ method given in desc to invoke below method, but could not fetch complete stack. `private Consumer super Throwable> logError(Try httpEntity, Subscriber super String> subscriber){ LOGGER.info("Error occured {} {}",httpEntity,subscriber); return null; }` I am making a http call and if something goes wrong while processing response or if response itself is 500 then entire stacktrace has to be logged. **Sorry if ask is silly,new to vavr – Jai Apr 01 '18 at 21:44
  • Hi @Jai, a `Try` instance captures a [non-fatal](https://static.javadoc.io/io.vavr/vavr/0.9.2/io/vavr/control/Try.html) exception by including the original exception as-is. In your code you rely on the `toString` method of `Try` when logging it. In the case of a failure `toString` is defined to be `"Failure(" + cause + ")"`, where `cause` is the exception that was internally catched by `Try`. You might want to access the original exception using [`getCause()`](https://static.javadoc.io/io.vavr/vavr/0.9.2/io/vavr/control/Try.html#getCause--). – Daniel Dietrich Apr 02 '18 at 12:26
  • Hi @daniel, when i try to use httpEntity.getCause method in the logger it fails with an exception `java.lang.UnsupportedOperationException: getCause on Success at javaslang.control.Try$Success.getCause(Try.java:698)' I am not very sure how to log an stack trace of exception when the service i am trying to access return a 500 or any other exception occurs while processing the response. Moreover if server returns a 500, then onFailure block of code gets triggered but why would getCause fails with error _getCause of Success_ – Jai Apr 02 '18 at 13:12
  • You have to ensure that it is a failure by calling `if (httpEntity.isFailure()) { ... }`. But in your case it might be more straight-forward to use the fluent API `httpEntity.onFailure(e -> { /*do something with exception e*/ })`. – Daniel Dietrich Apr 02 '18 at 21:13
  • I did tried to log error by `httpEntity.onFailure(e -> { LOGGER.info("Error "+e)*/ })` but nothing gets logged. Infact httpEntity.isFailure() is returning false. So the problem is if the server is gonna respond with 500 then httpEntity.onFailure gets executed but httpEntity.isFailure is returning false. But ideally for response 500 should be considered as failure and httpEntity.isFailure should have returned true. – Jai Apr 03 '18 at 12:18
  • This sounds like the `Try` instance is a success that encapsulates a valid http response object. If so, `isFailure` of course will return `false` and the handler passed to `onFailure()` will not be executed. You might need to handle the 500 code in an `onSuccess()` handler instead. But without seeing the complete code (and 3rd party API) I can only guess. – Daniel Dietrich Apr 04 '18 at 11:42