Добавьте больше контекста к исключению или ошибке в Groovy - PullRequest
1 голос
/ 13 мая 2019

Когда я хочу просто добавить больше контекста к любому произошедшему исключению (включая ошибки синтаксического анализа и даже нехватку памяти), я пишу код следующим образом

    try {
        new JsonSlurper().parseText(response)
    } catch (any) {
        throw new IllegalStateException("Cannot parse response:\n$response", any)
    }

Это работает нормально, но я могу закончить* * * * * * * * * * * * * * * * * * * * * * * * *

Есть ли способ просто добавить больше контекста к исключению с OutOfMemoryError, заключенным в IllegalStateException, что не звучит правильно, поскольку в дальнейшем может быть выделен механизм обработки исключений только для Error throwables. *1007* *1008*и все же сохранить свой первоначальный тип или категорию?Т.е. когда я получаю OOME, я хочу перебросить Error, когда я получаю какое-то исключение при разборе, я хочу отбрасывать какое-то непроверенное исключение и т. Д. И, конечно, я не хочу делать это вручную для каждой категории, так как OOME довольно маловероятно, и я не хочу создавать специальный код для угловых случаев (хотя все же я хочу быть технически правильным).

1 Ответ

0 голосов
/ 18 мая 2019

Вы можете определенно сделать это в Groovy, используя функции metaprogramming .В частности, для вашего случая метаклассы предоставляют все необходимое.Используя их, вы можете динамически добавлять / присоединять объект contextData к exception, который вы хотите носить с собой:

    private static void throwsEnhancedException() throws IOException {
        try {
            throwsBasicException()
        } catch (IOException e) {
            e.metaClass.contextData = "My context data"
            throw e;
        }
    }

Затем, чтобы извлечь contextData в других частях кода, просто проверьтеexception объект, подобный следующему:

    private static void doSomethingWithContextData(Closure contextDataHandler) throws IOException {
        try {
            throwsEnhancedException();
        } catch (IOException e) {
            // RETRIEVE `contextData` FROM `e` OR NULL IF THE PROPERTY DO NOT EXIST
            def contextData = e.hasProperty('contextData')?.getProperty(e)

            // DO SOMETHING WITH `contextData`
            contextDataHandler(contextData)
        }
    }

Здесь я использую аргумент contextDataHandler как отличный Closure для гибкой обработки contextData.

Ниже приводится полная рабочая демонстрация этого:

import java.time.LocalDateTime

class ExceptionEnhancer {
    static void main(String[] args) {
        def logger = { println "${LocalDateTime.now()} - Context Data = [$it]" }
        doSomethingWithContextData logger
    }

    private static void doSomethingWithContextData(Closure contextDataHandler) throws IOException {
        try {
            throwsEnhancedException();
        } catch (IOException e) {
            // RETRIEVE `contextData` FROM `e` OR NULL IF THE PROPERTY DO NOT EXIST
            def contextData = e.hasProperty('contextData')?.getProperty(e)

            // DO SOMETHING WITH `contextData`
            contextDataHandler(contextData)
        }
    }

    private static void throwsEnhancedException() throws IOException {
        try {
            throwsBasicException()
        } catch (IOException e) {
            e.metaClass.contextData = "My context data"
            throw e;
        }
    }

    public static void throwsBasicException() throws IOException {
        throw new IOException();
    }
}

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...