# V6051. Use of jump statements in 'finally' block can lead to the loss of unhandled exceptions.

Анализатор выявил использование операторов return/break/continue и т.п. внутри блока 'finally'. Их использование может привести к потере необработанного исключения, возникшего в блоках 'try' или 'catch'. Согласно JLS [14.20.2], в случае такого завершения блока 'finally', все сгенерированные исключения в 'try' или 'catch' будут подавлены.

Рассмотрим пример, когда анализатор выдаст предупреждение:

    int someMethod(int a, int b, int c) throws SomeException
    {
      int value = -1;
      ...
      try
      {
        value = calculateTransform(a, b, c);
        ...
      }
      finally
      {
        System.out.println("Result of someMethod()");
        return value;                                  // <=
      }
    }

В данном примере, несмотря на то, что в сигнатуре метода указано, что может возникнуть исключение, метод 'someMethod' никогда не выбросит его, так как применение оператора 'return' подавит исключение, и оно не выйдет наружу.

Возможно, это намеренный способ подавления исключений. В таком случае, чтобы анализатор не ругался, достаточно убрать исключение из сигнатуры метода.

    int someMethod(int a, int b, int c)
    {
      int value = -1;
      ...
      try
      {
        value = calculateTransform(a, b, c);
        ...
      }
      finally
      {
        System.out.println("Result of someMethod()");
        return value;
      }
    }

Немного изменим предыдущий пример:

    int someMethod(int a, int b, int c) throws SomeException
    {
      int value = -1;
      ...
      try
      {
        value = calculateTransform(a, b, c);
        ...
      }
      catch (SomeException se)
      {
        ...
        throw se;
      }
      finally
      {
        System.out.println("Result of someMethod()");
        return value;                                  // <=
      }
    }

Здесь анализатор тоже выдаст предупреждение. Есть обработчик исключения 'SomeException', который что-то делает и пробрасывает это исключение дальше. После чего отработает блок 'finally' и функция вернет значение 'value'. А что же исключение? А исключение, что было проброшено дальше в обработчике, так и не выйдет за пределы метода.

Чтобы исправить ситуацию, можно исправить код следующим образом:

    int someMethod(int a, int b, int c) throws SomeException
    {
      int value = -1;
      ...
      try
      {
        value = calculateTransform(a, b, c);
        ...
      }
      catch (SomeException se)
      {
        ...
        throw se;
      }
      finally
      {
        System.out.println("Result of someMethod()");
      }
      return value;
    }

В таком случае, если произошло исключение, то оно будет обязательно проброшено наружу, что и говорит сигнатура метода 'someMethod'.

Данная диагностика классифицируется как:

CWE-584 CERT-ERR04-J

Взгляните на примеры ошибок, обнаруженных с помощью диагностики V6051.