What is the most likely cause of exceptions that mysteriously avoid the try-catch block in this case?

I am using Spring WebClient in a Kotlin project , for example:

data class DTO(val name: String)

@Component
class Runner: ApplicationRunner
{
    override fun run(args: ApplicationArguments?)
    {
        try
        {
            val dto = get<DTO>()
        }
        catch (e: Exception)
        {
            println("ERROR, all exceptions should have been caught in 'get' ")
        }
    }
}

inline private fun<reified TResult: Any> get(): TResult?
{
    var result: TResult? = null

    try
    {
    result = WebClient.create("https://maps.googleapis.com/maps/api/nonexisting")
        .get()
        .retrieve()
        .bodyToMono<TResult>()
        .block()
    }
    catch (e: Exception)
    {
        println("WORKS AS EXPECTED!!")
    }

    return result
}

The client will throw an exception because the API will return 404. However, the exception is not caught where it should be, namely in the body of the function get, but it extends to the external exception handler.

It is interesting to note that this only happens if an exception is thrown WebClient. If I replaced the code in the sentence with a trysimple one throw Exception("error"), the exception will be caught where it should be.

Similarly, when I change the signature getto a non-generic one inline private fun get(): DTO? , the problem also disappears.

, try-catch, Kotlin. , , WebClient, , Spring. , .

, . , , . , , :

enter image description here

Spring Boot 2.0.0.M6, M5.

, Spring, Kotlin. , , , , , -, , .

+4
2

Spring Boot version 2.0.0.M5 2.0.0.M6, , :

result = WebClient.create("https://maps.googleapis.com/maps/api/nonexisting")
    .get()
    .retrieve()
    .bodyToMono<TResult>()
    .block()

- , Spring Boot 2.0.0.M5, WebClientResponseException , Spring Boot 2.0.0.M6 .

e.printStackTrace() catch, , :

java.lang.ClassCastException: org.springframework.web.reactive.function.client.WebClientResponseException com.example.demo.DTO com.example.demo.Runner.run(Test.kt: 18) at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:780)    org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:770)    org.springframework.boot.SpringApplication.afterRefresh(SpringApplication.java:760)    org.springframework.boot.SpringApplication.run(SpringApplication.java:328)    org.springframework.boot.SpringApplication.run(SpringApplication.java:1245)    org.springframework.boot.SpringApplication.run(SpringApplication.java:1233)   at com.example.demo.DemoApplicationKt.main(DemoApplication.kt: 10)

, , WebClientResponseException DTO val dto = get<DTO>(). , result = ..., . , , , get<Object>() get<DTO>(), catch.

- IntelliJ Idea, Java, :

public class Runner implements ApplicationRunner {
   public void run(@Nullable ApplicationArguments args) {
      try {
         Object result$iv = null;

         try {
            ResponseSpec $receiver$iv$iv = WebClient.create("https://maps.googleapis.com/maps/api/nonexisting").get().retrieve();
            Mono var10000 = $receiver$iv$iv.bodyToMono((ParameterizedTypeReference)(new Runner$run$$inlined$get$1()));
            Intrinsics.checkExpressionValueIsNotNull(var10000, "bodyToMono(object : Para…zedTypeReference<T>() {})");
            result$iv = var10000.block();
         } catch (Exception var7) {
            String var5 = "WORKS AS EXPECTED!!";
            System.out.println(var5);
         }

         DTO var2 = (DTO)result$iv;
      } catch (Exception var8) {
         String var3 = "ERROR, all exceptions should have been caught in 'get' ";
         System.out.println(var3);
      }

   }
}

, DTO ( , ), catch: DTO var2 = (DTO)result$iv;. , reified.

+7

SPR-16025 (. ), Kotlin ParameterizedTypeReference, Spring Framework 5.0.1 Spring Boot 2.0.0.M6.

, bodyToMono(TResult::class.java) Spring Boot 2.0.0.M5, , .

+4

Source: https://habr.com/ru/post/1689561/


All Articles