Class ExceptionThrowShouldUseContextCheck

All Implemented Interfaces:
Configurable, Contextualizable

Checks that exception throw statements in catch blocks use context variables.

Rationale: When catching an exception and throwing a new exception, it is recommended to include contextual information in the new exception constructor (such as method parameters, local variables declared outside the catch block, or fields). Failing to include context makes troubleshooting and debugging production issues significantly harder.

Since:
14.4.0
  • Field Details

  • Constructor Details

  • Method Details

    • getDefaultTokens

      public int[] getDefaultTokens()
      Description copied from class: AbstractCheck
      Returns the default token a check is interested in. Only used if the configuration for a check does not define the tokens.
      Specified by:
      getDefaultTokens in class AbstractCheck
      Returns:
      the default tokens
      See Also:
    • getAcceptableTokens

      public int[] getAcceptableTokens()
      Description copied from class: AbstractCheck
      The configurable token set. Used to protect Checks against malicious users who specify an unacceptable token set in the configuration file. The default implementation returns the check's default tokens.
      Specified by:
      getAcceptableTokens in class AbstractCheck
      Returns:
      the token set this check is designed for.
      See Also:
    • getRequiredTokens

      public int[] getRequiredTokens()
      Description copied from class: AbstractCheck
      The tokens that this check must be registered for.
      Specified by:
      getRequiredTokens in class AbstractCheck
      Returns:
      the token set this must be registered for.
      See Also:
    • visitToken

      public void visitToken(DetailAST ast)
      Description copied from class: AbstractCheck
      Called to process a token.
      Overrides:
      visitToken in class AbstractCheck
      Parameters:
      ast - the token to process
    • isThrowWithoutContext

      private static boolean isThrowWithoutContext(DetailAST throwAst, String catchParamName, DetailAST catchAst)
      Checks if a throw statement throws a new exception without using context variables.
      Parameters:
      throwAst - throw statement ast
      catchParamName - name of the catch parameter
      catchAst - enclosing catch ast
      Returns:
      true if the throw statement throws a new exception without using context variables
    • collectThrowStatements

      private static void collectThrowStatements(DetailAST node, List<DetailAST> result)
      Recursively collects all throw statements in a block, skipping nested catches, classes, records, interfaces, and lambdas.
      Parameters:
      node - AST node to search
      result - list to collect throw statements into
    • containsAnyVariable

      private static boolean containsAnyVariable(DetailAST node, Set<String> variables, String excludedName)
      Checks if an AST node contains any identifier from the variable set, excluding a given name.
      Parameters:
      node - AST node to search
      variables - set of variable names
      excludedName - identifier name to exclude
      Returns:
      true if any variable is found
    • collectContextVariables

      private static Set<String> collectContextVariables(DetailAST catchAst, String catchParamName)
      Collects all available context variables in scope: parameters, local variables outside the catch block, applicable enclosing class fields, and variables initialized with context inside the catch block.
      Parameters:
      catchAst - catch AST node
      catchParamName - catch parameter name
      Returns:
      set of available context variable names
    • findEnclosingMethodScopes

      Finds all enclosing method-like scopes (methods, constructors, or lambdas).
      Parameters:
      node - starting AST node
      Returns:
      list of enclosing method-like AST nodes
    • isStaticScope

      private static boolean isStaticScope(Iterable<DetailAST> methodScopes)
      Checks if any of the enclosing method scopes is declared static.
      Parameters:
      methodScopes - method-like scopes
      Returns:
      true if any enclosing scope is static
    • collectParameters

      private static void collectParameters(DetailAST methodAst, Set<String> contextVars)
      Collects parameters from a method, constructor, or lambda.
      Parameters:
      methodAst - method-like AST node
      contextVars - set to add parameter names to
    • collectCompactCtorParameters

      private static void collectCompactCtorParameters(DetailAST compactCtorDef, Set<String> contextVars)
      Collects parameters from a compact constructor in a record.
      Parameters:
      compactCtorDef - compact constructor AST node
      contextVars - set to add parameter names to
    • addRecordComponents

      private static void addRecordComponents(DetailAST recordComponents, Set<String> contextVars)
      Adds record component names to context variables.
      Parameters:
      recordComponents - record components AST node
      contextVars - set to add component names to
    • collectStandardParameters

      private static void collectStandardParameters(DetailAST methodAst, Set<String> contextVars)
      Collects parameters from a standard method, constructor, or lambda.
      Parameters:
      methodAst - method-like AST node
      contextVars - set to add parameter names to
    • collectLocalVariablesOutsideCatch

      private static void collectLocalVariablesOutsideCatch(DetailAST node, DetailAST catchAst, Set<String> contextVars)
      Recursively collects local variables within a method, skipping the catch AST node and nested types.
      Parameters:
      node - AST node to search
      catchAst - catch AST node to skip
      contextVars - set to add variable names to
    • collectCatchVariablesWithContext

      private static void collectCatchVariablesWithContext(DetailAST catchAst, Set<String> contextVars, String catchParamName)
      Collects variables declared within the catch block whose initializers reference an already identified context variable.
      Parameters:
      catchAst - catch AST node
      contextVars - set of known context variables
      catchParamName - catch parameter name
    • processLocalVariableDef

      private static void processLocalVariableDef(DetailAST child, Set<String> contextVars)
      Processes a child node and adds any defined local variable name to context variables.
      Parameters:
      child - AST node to inspect
      contextVars - set to add variable names to
    • isInnerClass

      private static boolean isInnerClass(DetailAST classDef)
      Checks if an enclosing class is a non-static inner class.
      Parameters:
      classDef - class AST node
      Returns:
      true if the class is a non-static inner class
    • findEnclosingClassLike

      Finds the nearest enclosing class, record, interface, or enum.
      Parameters:
      node - starting AST node
      Returns:
      enclosing type AST node, or null if none
    • collectFields

      private static void collectFields(DetailAST classDef, Set<String> contextVars, boolean isStaticMethod)
      Collects field names from an enclosing type's object block, filtering out instance fields when within a static scope.
      Parameters:
      classDef - enclosing type AST node
      contextVars - set to add field names to
      isStaticMethod - true if enclosing method is static