All files / src/rules rfc_error_handling.ts

100% Statements 85/85
100% Branches 18/18
100% Functions 6/6
100% Lines 85/85

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 851x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 11278x 11278x 11278x 11278x 33677x 33677x 33677x 33677x 33677x 33677x 33677x 33677x 33677x 33677x 33677x 33677x 33677x 33677x 33677x 33677x 33677x 11278x 11278x 2x 2x 11278x 11278x 10789x 10789x 11278x 11278x 229x 229x 11278x 11278x 244x 244x 244x 1372x 1372x 1372x 1368x 1368x 4x 1372x 1x 1x 3x 3x 1372x 1x 1x 1x 1x 2x 2x 2x 1372x 6x 6x 2x 2x 1372x 1372x 1x 1x 1x 1x 1372x 244x 244x 244x 11278x 11278x
import {Issue} from "../issue";
import {ABAPRule} from "./_abap_rule";
import {BasicRuleConfig} from "./_basic_rule_config";
import * as Statements from "../abap/2_statements/statements";
import * as Expressions from "../abap/2_statements/expressions";
import {IRuleMetadata, RuleTag} from "./_irule";
import {ABAPFile} from "../abap/abap_file";
 
export class RFCErrorHandlingConf extends BasicRuleConfig {
}
 
export class RFCErrorHandling extends ABAPRule {
  private conf = new RFCErrorHandlingConf();
 
  public getMetadata(): IRuleMetadata {
    return {
      key: "rfc_error_handling",
      title: "RFC error handling",
      tags: [RuleTag.SingleFile],
      shortDescription: `Checks that exceptions 'system_failure' and 'communication_failure' are handled in RFC calls`,
      extendedInformation: `https://help.sap.com/doc/abapdocu_750_index_htm/7.50/en-US/abenrfc_exception.htm`,
      badExample: `CALL FUNCTION 'ZRFC'
  DESTINATION lv_rfc.`,
      goodExample: `CALL FUNCTION 'ZRFC'
  DESTINATION lv_rfc
  EXCEPTIONS
    system_failure        = 1 MESSAGE msg
    communication_failure = 2 MESSAGE msg
    resource_failure      = 3
    OTHERS                = 4.`,
    };
  }
 
  private getMessage(): string {
    return "RFC error handling: At least one unhandled exception from SYSTEM_FAILURE, COMMUNICATION_FAILURE, RESOURCE_FAILURE";
  }
 
  public getConfig() {
    return this.conf;
  }
 
  public setConfig(conf: RFCErrorHandlingConf) {
    this.conf = conf;
  }
 
  public runParsed(file: ABAPFile) {
    const output: Issue[] = [];
 
    for (const stat of file.getStatements()) {
      const token = stat.getFirstToken();
 
      if (!(stat.get() instanceof Statements.CallFunction)) {
        continue;
      }
 
      if (!stat.findFirstExpression(Expressions.Destination)) {
        continue;
      }
 
      const list = stat.findFirstExpression(Expressions.ParameterListExceptions);
      if (list === undefined) {
        const issue = Issue.atToken(file, token, this.getMessage(), this.getMetadata().key, this.conf.severity);
        output.push(issue);
        continue;
      }
 
      const parameters = list.findAllExpressions(Expressions.ParameterName);
      const names: string[] = [];
      for (const par of parameters) {
        names.push(par.getFirstToken().getStr().toUpperCase());
      }
 
      if (names.indexOf("SYSTEM_FAILURE") < 0
          || names.indexOf("COMMUNICATION_FAILURE") < 0
          || names.indexOf("RESOURCE_FAILURE") < 0) {
        const issue = Issue.atToken(file, token, this.getMessage(), this.getMetadata().key, this.conf.severity);
        output.push(issue);
        continue;
      }
    }
 
    return output;
  }
 
}