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

Bare "raise" statements should only be used in "except" blocks

    XMLWordPrintable

    Details

    • Message:
      Remove this "raise" statement or move it inside an "except" block.
    • Highlighting:
      Hide

      The raise statement

      Show
      The raise statement
    • Default Severity:
      Critical
    • Impact:
      High
    • Likelihood:
      Low
    • Default Quality Profiles:
      Sonar way
    • Covered Languages:
      Python
    • Remediation Function:
      Constant/Issue
    • Constant Cost:
      10min
    • Analysis Level:
      Syntactic Analysis
    • 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 the "raise" statement is not in an except or finally block, no exception is active and a RuntimeError is raised instead.

      If the bare raise statement is in a function called in an except statement, the exception caught by the except will be raised. This works but is hard to understand and maintain. Nothing indicates in the parent except that the exception will be reraised, and nothing prevents a developer from calling the function in another context.

      Note also that using a bare raise in a finally block only works when an exception is active, i.e. when an exception from the try block is not caught or when an exception is raised by an except block. It will fail in any other case and should not be relied upon. This code smell is handled by rule S5704.

      This rule raises an exception when a bare raise statement is not in an except or finally block.

      Noncompliant Code Example

      raise  # Noncompliant
      
      def foo():
          raise  # Noncompliant
          try:
              raise  # Noncompliant
          except ValueError as e:
              handle_error()
          except:
              raise
          else:
              raise  # Noncompliant
          finally:
              raise
      
      def handle_error():
          raise  # Noncompliant. This works but is hard to understand.
      

      Compliant Solution

      raise ValueError()
      
      def foo():
          raise ValueError()
          try:
              raise ValueError()
          except:
              raise
          else:
              raise ValueError()
          finally:
              raise
      

      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: