Uploaded image for project: 'Rules Repository'
  1. Rules Repository
  2. RSPEC-5704

Bare "raise" statements should not be used in "finally" blocks

    XMLWordPrintable

    Details

    • Message:
      Refactor this code so that any active exception raises naturally
    • Highlighting:
      Hide

      Primary:

      • The bare "raise" statement

      Secondary:

      • the parent "finally:" statement
      Show
      Primary: The bare "raise" statement Secondary: the parent "finally:" statement
    • Default Severity:
      Critical
    • Impact:
      High
    • Likelihood:
      Low
    • Default Quality Profiles:
      Sonar way
    • Covered Languages:
      Python
    • Irrelevant for Languages:
      ABAP, APEX, C#, C, C++, Cobol, CSS, Flex, Go, HTML, Java, JavaScript, Kotlin, Objective-C, PHP, PL/I, PL/SQL, RPG, Ruby, Rust, Scala, Solidity, Swift, T-SQL, TypeScript, VB.Net, VB6, XML
    • Remediation Function:
      Constant/Issue
    • Constant Cost:
      30min
    • Analysis Scope:
      Main Sources, Test Sources

      Description

      A bare raise statement, i.e. a raise with no exception provided, will re-raise the last active exception in the current scope. If no exception is active a RuntimeError is raised instead.
      If the bare "raise" statement is in a finally block, it will only have an active exception to re-raise when an exception from the try block is not caught or when an exception is raised by an except or else block. Thus bare raise statements should not be relied upon in finally blocks. It is simpler to let the exception raise automatically.

      This rule raises an issue when a bare raise statements is in a finally block.

      Noncompliant Code Example

      def foo(param):
          result = 0
          try:
              print("foo")
          except ValueError as e:
              pass
          else:
              if param:
                  raise ValueError()
          finally:
              if param:
                  raise  # Noncompliant. This will fail in some context.
              else:
                  result = 1
          return result
      

      Compliant Solution

      def foo(param):
          result = 0
          try:
              print("foo")
          except ValueError as e:
              pass
          else:
              if param:
                  raise ValueError()
          finally:
              if not param:
                  result = 1
              # the exception will raise automatically
          return result
      

      See

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              Unassigned Unassigned
              Reporter:
              nicolas.harraudeau Nicolas Harraudeau (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

                Dates

                Created:
                Updated: