Обработка / подавление исключений с функцией более высокого порядка - PullRequest
0 голосов
/ 23 января 2019

У меня есть приложение в микросервисной архитектуре.Это приложение получает данные из разных источников и получает много разных сообщений об ошибках от различных других приложений.Некоторые исключения, такие как 404-Не найденные исключения, могут быть сгенерированы и возвращены конечному пользователю, но другие исключения (плохие запросы, ++) не могут и должны быть подавлены, вызывая некоторые другие исключения.

Тем не менее, я знаю, что это можно решить путем try-catch исключения и модерирования того, что бросить в этом вопросе, но это потребовало бы большого количества кода ... иногда я хочу принять 4-5 различных исключенийВ то время как другие времена только 1-2 исключения.


Во всяком случае .. Мне нужна помощь в создании функции более высокого порядка.Мне нужна функция, которая принимает одно или несколько «принятых исключений» в качестве параметров (они являются исключениями времени выполнения) и выдает только утвержденные исключения в try-catch.

Это то, что я пробовал, , но, похоже, синтаксис не может быть правильным (псевдокод атм.).Любая помощь очень ценится.

  fun getData() {
    return supressExceptions(
        NotFoundException::class.java, 
        ForbiddenException::class.java, 
        AuthorizationException::class.java) {
      service.getData()
    }
  }

  private inline fun <T, X : RuntimeException> supressExceptions(vararg approvedException: Class<X>, block: () -> T): T =
      try {
        block()
      } catch (ex: Exception) {
        // Loop through the approved exceptions.
        // Throw the approved exception
        throw ex
        // ELSE: do something else if the exception is not approved.
      }

Ответы [ 3 ]

0 голосов
/ 23 января 2019

Это может быть достигнуто с помощью any:

  private inline fun <T, X : RuntimeException> supressExceptions(vararg approvedException: Class<X>,
      block: () -> T): T =
      try {
        block()
      } catch (ex: Exception) {
        when {
          approvedException.any { ex::class.java == it } -> throw ex
          else -> {
            throw SupressedException(ex)
          }
        }
      }

any : Возвращает true, если хотя бы одна запись соответствует данному предикату.

0 голосов
/ 23 января 2019

Как уже упоминалось в комментариях: от именования я бы ожидал, что suppressExceptions скорее принимает параметр исключений, которые должны быть подавлены.

Интересно, хотите ли вы на самом деле проверить, является ли выброшенное исключение на самом деле экземпляром данных типов исключений, т. Е. Должны ли быть утверждены / исключены также подклассы указанных типов.

В таком случае я бы предпочел использовать следующий код:

inline fun <T> suppressAllExceptions(vararg exceptExceptions: Class<out Exception> = emptyArray(),
                                     block: () -> T) = try {
  block()
} catch (e: Exception) {
  throw if (exceptExceptions.any { it.isInstance(e) }) {
    e
  } else SuppressedException(e)
}

Вы бы все равно использовали его так же, как показали:

suppressAllExceptions {
  throw IllegalStateException("i am suppressed soon")
}
suppressAllExceptions(IllegalStateException::class.java, 
                      IllegalArgumentException::class.java) {
  throw IllegalStateException("i am not suppressed")
}
class MyIllegalStateException : IllegalStateException()
suppressAllExceptions(IllegalStateException::class.java, 
                      IllegalArgumentException::class.java) {
  throw MyIllegalStateException("i am not suppressed neither")
} 

Чем больше я об этом думаю: почему вы одобряете разные типы исключений в разных местах? Это не звучит правильно для меня. Скорее всего, вы хотите подавить все исключения, кроме некоторых четко определенных, и в таком случае вам не нужна такая универсальная функция, а есть одна функция подавления, которая содержит этот четко определенный список:

/**
 * Suppresses all exceptions except the well-defined ones: [NotFoundException], ...
 */
inline fun <T> suppressExceptions(block: () -> T) = try {
  block()
} catch (e: Exception) {
  throw when (e) {
    is NotFoundException,
    is ForbiddenException,
    // all the other well-defined non-suppressable types
    is AuthorizationException -> e
    else -> SuppressedException(e)
  }
}
0 голосов
/ 23 января 2019

Это то, что вы ищете ниже?

private inline fun <T> supressExceptions(vararg approvedException: Class<out RuntimeException>, block: () -> T): T =
        try {
            block()
        } catch (ex: Exception) {
            if (approvedException.contains(ex::class.java)) {
                // Approved exception
                throw ex
            }
            // ELSE: do something else if the exception is not approved.
            else throw Exception("Something else")
        }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...