init()

in Sources/ArgumentParser/Usage/MessageInfo.swift [19:129]


  init(error: Error, type: ParsableArguments.Type) {
    var commandStack: [ParsableCommand.Type]
    var parserError: ParserError? = nil
    
    switch error {
    case let e as CommandError:
      commandStack = e.commandStack
      parserError = e.parserError

      // Exit early on built-in requests
      switch e.parserError {
      case .helpRequested:
        self = .help(text: HelpGenerator(commandStack: e.commandStack).rendered())
        return


      case .dumpHelpRequested:
        self = .help(text: DumpHelpGenerator(commandStack: e.commandStack).rendered())
        return

      case .versionRequested:
        let versionString = commandStack
          .map { $0.configuration.version }
          .last(where: { !$0.isEmpty })
          ?? "Unspecified version"
        self = .help(text: versionString)
        return
        
      case .completionScriptRequested(let shell):
        do {
          let completionsGenerator = try CompletionsGenerator(command: type.asCommand, shellName: shell)
          self = .help(text: completionsGenerator.generateCompletionScript())
          return
        } catch {
          self.init(error: error, type: type)
          return
        }

      case .completionScriptCustomResponse(let output):
        self = .help(text: output)
        return
        
      default:
        break
      }
      
    case let e as ParserError:
      // Send ParserErrors back through the CommandError path
      self.init(error: CommandError(commandStack: [type.asCommand], parserError: e), type: type)
      return

    default:
      commandStack = [type.asCommand]
      // if the error wasn't one of our two Error types, wrap it as a userValidationError
      // to be handled appropriately below
      parserError = .userValidationError(error)
    }
    
    var usage = HelpGenerator(commandStack: commandStack).usageMessage()
    
    let commandNames = commandStack.map { $0._commandName }.joined(separator: " ")
    if let helpName = commandStack.getPrimaryHelpName() {
      usage += "\n  See '\(commandNames) \(helpName.synopsisString)' for more information."
    }
    
    // Parsing errors and user-thrown validation errors have the usage
    // string attached. Other errors just get the error message.
    
    if case .userValidationError(let error) = parserError {
      switch error {
      case let error as ValidationError:
        self = .validation(message: error.message, usage: usage, help: "")
      case let error as CleanExit:
        switch error.base {
        case .helpRequest(let command):
          if let command = command {
            commandStack = CommandParser(type.asCommand).commandStack(for: command)
          }
          self = .help(text: HelpGenerator(commandStack: commandStack).rendered())
        case .dumpRequest(let command):
          if let command = command {
            commandStack = CommandParser(type.asCommand).commandStack(for: command)
          }
          self = .help(text: DumpHelpGenerator(commandStack: commandStack).rendered())
        case .message(let message):
          self = .help(text: message)
        }
      case let error as ExitCode:
        self = .other(message: "", exitCode: error.rawValue)
      case let error as LocalizedError where error.errorDescription != nil:
        self = .other(message: error.errorDescription!, exitCode: EXIT_FAILURE)
      default:
        if Swift.type(of: error) is NSError.Type {
          self = .other(message: error.localizedDescription, exitCode: EXIT_FAILURE)
        } else {
          self = .other(message: String(describing: error), exitCode: EXIT_FAILURE)
        }
      }
    } else if let parserError = parserError {
      let usage: String = {
        guard case ParserError.noArguments = parserError else { return usage }
        return "\n" + HelpGenerator(commandStack: [type.asCommand]).rendered()
      }()
      let argumentSet = ArgumentSet(commandStack.last!)
      let message = argumentSet.errorDescription(error: parserError) ?? ""
      let helpAbstract = argumentSet.helpDescription(error: parserError) ?? ""
      self = .validation(message: message, usage: usage, help: helpAbstract)
    } else {
      self = .other(message: String(describing: error), exitCode: EXIT_FAILURE)
    }
  }