🔥 변환 오류 처리하기
360자
4분
명령행 인자와 옵션을 파싱할 때, 클로저를 사용하여 명령행 문자열을 커스텀 타입으로 변환할 수 있습니다. 이 변환이 실패하면 ValidationError를 던질 수 있는데, 이때 message 속성이 사용자에게 표시됩니다.
또한, 개발자가 직접 정의한 오류를 던질 수도 있습니다. CustomStringConvertible 또는 LocalizedError를 준수하는 오류는 사용자에게 가장 좋은 경험을 제공합니다.
swift
struct ExampleTransformError: Error, CustomStringConvertible {
var description: String
}
// ExampleTransformError 구조체는 Error와 CustomStringConvertible 프로토콜을 준수합니다.
// description 속성은 오류에 대한 설명을 제공합니다.
struct ExampleDataModel: Codable {
let identifier: UUID
let tokens: [String]
let tokenCount: Int
static func dataModel(_ jsonString: String) throws -> ExampleDataModel {
guard let data = jsonString.data(using: .utf8) else {
throw ValidationError("Badly encoded string, should be UTF-8")
}
// jsonString을 UTF-8 인코딩을 사용하여 데이터로 변환합니다.
// 변환에 실패하면 ValidationError를 던집니다.
return try JSONDecoder().decode(ExampleDataModel.self, from: data)
// JSONDecoder를 사용하여 데이터를 ExampleDataModel 타입으로 디코딩합니다.
// 디코딩에 실패하면 오류를 던집니다.
}
}
struct Example: ParsableCommand {
@Argument(transform: ExampleDataModel.dataModel)
var inputJSON: ExampleDataModel
// inputJSON 인자는 명령행 문자열을 ExampleDataModel 객체로 변환하려고 시도합니다.
// 문자열이 유효한 JSON이 아니면 decode 메서드가 오류를 던지고 파싱이 중단됩니다.
@Option(transform: { throw ExampleTransformError(description: "Trying to write to failOption always produces an error. Input: \($0)") })
var failOption: String?
// failOption 옵션을 지정하면 항상 파서가 종료되고 사용자 정의 오류가 출력됩니다.
}
swift
struct ExampleTransformError: Error, CustomStringConvertible {
var description: String
}
// ExampleTransformError 구조체는 Error와 CustomStringConvertible 프로토콜을 준수합니다.
// description 속성은 오류에 대한 설명을 제공합니다.
struct ExampleDataModel: Codable {
let identifier: UUID
let tokens: [String]
let tokenCount: Int
static func dataModel(_ jsonString: String) throws -> ExampleDataModel {
guard let data = jsonString.data(using: .utf8) else {
throw ValidationError("Badly encoded string, should be UTF-8")
}
// jsonString을 UTF-8 인코딩을 사용하여 데이터로 변환합니다.
// 변환에 실패하면 ValidationError를 던집니다.
return try JSONDecoder().decode(ExampleDataModel.self, from: data)
// JSONDecoder를 사용하여 데이터를 ExampleDataModel 타입으로 디코딩합니다.
// 디코딩에 실패하면 오류를 던집니다.
}
}
struct Example: ParsableCommand {
@Argument(transform: ExampleDataModel.dataModel)
var inputJSON: ExampleDataModel
// inputJSON 인자는 명령행 문자열을 ExampleDataModel 객체로 변환하려고 시도합니다.
// 문자열이 유효한 JSON이 아니면 decode 메서드가 오류를 던지고 파싱이 중단됩니다.
@Option(transform: { throw ExampleTransformError(description: "Trying to write to failOption always produces an error. Input: \($0)") })
var failOption: String?
// failOption 옵션을 지정하면 항상 파서가 종료되고 사용자 정의 오류가 출력됩니다.
}
transform 클로저에서 오류를 던지면 컨텍스트를 제공하여 사용자에게 도움을 주고, 문제를 빠르고 정확하게 파악하여 개발 시간을 단축할 수 있습니다.
text
% example '{"Bad JSON"}'
Error: The value '{"Bad JSON"}' is invalid for '<input-json>': dataCorrupted(Swift.DecodingError.Context(codingPath: [], debugDescription: "The given data was not valid JSON.", underlyingError: Optional(Error Domain=NSCocoaErrorDomain Code=3840 "No value for key in object around character 11." UserInfo={NSDebugDescription=No value for key in object around character 11.})))
Usage: example <input-json> --fail-option <fail-option>
See 'select --help' for more information.
text
% example '{"Bad JSON"}'
Error: The value '{"Bad JSON"}' is invalid for '<input-json>': dataCorrupted(Swift.DecodingError.Context(codingPath: [], debugDescription: "The given data was not valid JSON.", underlyingError: Optional(Error Domain=NSCocoaErrorDomain Code=3840 "No value for key in object around character 11." UserInfo={NSDebugDescription=No value for key in object around character 11.})))
Usage: example <input-json> --fail-option <fail-option>
See 'select --help' for more information.
표준 라이브러리나 Foundation 오류를 던지면 컨텍스트가 추가되지만, 사용자 정의 오류는 사용자와 개발자에게 최상의 경험을 제공합니다.
text
% example '{"tokenCount":0,"tokens":[],"identifier":"F77D661C-C5B7-448E-9344-267B284F66AD"}' --fail-option="Some Text Here!"
Error: The value 'Some Text Here!' is invalid for '--fail-option <fail-option>': Trying to write to failOption always produces an error. Input: Some Text Here!
Usage: example <input-json> --fail-option <fail-option>
See 'select --help' for more information.
text
% example '{"tokenCount":0,"tokens":[],"identifier":"F77D661C-C5B7-448E-9344-267B284F66AD"}' --fail-option="Some Text Here!"
Error: The value 'Some Text Here!' is invalid for '--fail-option <fail-option>': Trying to write to failOption always produces an error. Input: Some Text Here!
Usage: example <input-json> --fail-option <fail-option>
See 'select --help' for more information.
이렇게 변환 오류를 적절히 처리하면 사용자에게 더 나은 경험을 제공할 수 있습니다. 오류 메시지를 명확하게 제공하고, 사용자 정의 오류를 활용하여 문제의 원인을 빠르게 파악할 수 있죠.










