🔥 검증 후 오류 처리하기

289자
4분

ArgumentParser에서 ValidationError 타입은 특별한 오류입니다. 검증 오류 메시지는 항상 적절한 사용법 문자열과 함께 제공됩니다. validate() 또는 run() 메서드에서 다른 오류를 던져서 검증과 관련이 없는 문제가 발생했음을 나타낼 수 있습니다. CustomStringConvertible 또는 LocalizedError를 준수하는 오류는 사용자에게 가장 좋은 경험을 제공합니다.

다음은 LineCount 구조체의 예시 코드입니다:

swift
struct LineCount: ParsableCommand {
    @Argument var file: String
 
    mutating func run() throws {
        // 지정된 파일의 내용을 UTF-8 인코딩으로 읽어옵니다.
        let contents = try String(contentsOfFile: file, encoding: .utf8)
        // 줄 바꿈 문자를 기준으로 내용을 분할합니다.
        let lines = contents.split(separator: "\n")
        // 줄 수를 출력합니다.
        print(lines.count)
    }
}
 
swift
struct LineCount: ParsableCommand {
    @Argument var file: String
 
    mutating func run() throws {
        // 지정된 파일의 내용을 UTF-8 인코딩으로 읽어옵니다.
        let contents = try String(contentsOfFile: file, encoding: .utf8)
        // 줄 바꿈 문자를 기준으로 내용을 분할합니다.
        let lines = contents.split(separator: "\n")
        // 줄 수를 출력합니다.
        print(lines.count)
    }
}
 

사용자가 잘못된 파일을 지정하면 String(contentsOfFile:encoding:) 이니셜라이저가 실패합니다. ArgumentParser는 오류 메시지를 표준 오류로 출력하고 오류 코드와 함께 종료합니다.

text
% line-count file1.swift
37
% line-count non-existing-file.swift
Error: The file "non-existing-file.swift" couldn't be opened because
there is no such file.
text
% line-count file1.swift
37
% line-count non-existing-file.swift
Error: The file "non-existing-file.swift" couldn't be opened because
there is no such file.

오류 출력을 직접 출력하는 경우에도 적절한 종료 코드로 명령이 종료되도록 validate() 또는 run()에서 오류를 던져야 합니다. 추가 오류 메시지 출력을 피하려면 성공, 실패 및 검증 오류에 대한 정적 속성이 있거나 특정 종료 코드를 지정할 수 있는 ExitCode 오류를 사용하면 됩니다.

다음은 RuntimeError 구조체와 Example 구조체의 예시 코드입니다:

swift
struct RuntimeError: Error, CustomStringConvertible {
    var description: String
}
 
struct Example: ParsableCommand {
    @Argument var inputFile: String
 
    mutating func run() throws {
        // ExampleCore.processFile(_:) 메서드를 호출하여 파일 처리를 시도합니다.
        if !ExampleCore.processFile(inputFile) {
            // 파일 처리에 실패한 경우 ExampleCore.processFile(_:)이 자체 오류를 출력하고 false를 반환합니다.
            // 이 경우 ExitCode.failure 오류를 던져 명령을 종료합니다.
            throw ExitCode.failure
        }
    }
}
 
swift
struct RuntimeError: Error, CustomStringConvertible {
    var description: String
}
 
struct Example: ParsableCommand {
    @Argument var inputFile: String
 
    mutating func run() throws {
        // ExampleCore.processFile(_:) 메서드를 호출하여 파일 처리를 시도합니다.
        if !ExampleCore.processFile(inputFile) {
            // 파일 처리에 실패한 경우 ExampleCore.processFile(_:)이 자체 오류를 출력하고 false를 반환합니다.
            // 이 경우 ExitCode.failure 오류를 던져 명령을 종료합니다.
            throw ExitCode.failure
        }
    }
}
 

위 예시에서는 ExampleCore.processFile(_:) 메서드가 자체적으로 오류를 출력하고 실패 시 false를 반환한다고 가정합니다. 파일 처리에 실패한 경우 ExitCode.failure 오류를 던져서 명령을 종료합니다.

이렇게 ValidationError를 사용하여 검증 관련 오류를 처리하고, 다른 오류 타입을 사용하여 검증 이외의 오류를 처리할 수 있습니다. 오류 메시지를 직접 출력하는 경우에도 적절한 종료 코드로 명령이 종료되도록 주의해야 합니다.

YouTube 영상

채널 보기
동적 모듈 이해하기 | NestJS 가이드
미들웨어 적용과 라우팅 | NestJS 가이드
함수형 미들웨어 | NestJS 가이드
펑터란? | 프로그래머를 위한 카테고리 이론
모듈과 프로바이더 | NestJS 가이드
생성자 지옥에서 벗어나는 DI 방법 | NestJS 가이드
합타입 + 곱타입 = 강력한 타입 시스템? 대수적 데이터 타입의 비밀 | 프로그래머를 위한 카테고리 이론
곱, 프로덕트 | 프로그래머를 위한 카테고리 이론