#swift
#swift
Вопрос:
У меня есть следующая реализация, и я распространяю проблемы на ViewController для правильного отображения предупреждения. Как вы видите в моем коде, я использую guard let и пробую все вместе в одной строке. Я думаю, это работает, но не рекомендуется.
Что было бы наилучшим для обработки / рефакторинга кода для правильной обработки каждого случая броска?
enum ServiceError: Error {
case ClassroomApplicationCreation(Error)
case ClassroomDoesNotExist(Error)
case ClassRoomSelectionError
}
func createClassroom() throws -> String {
guard let selectedClass = try findClassroom() else {
throw ServiceError.ClassSelectionError
}
guard let classURL = URL(string: selectedClass) else {
throw ServiceError.ClassroomDoesNotExist
}
let authority = try Authority(url: classURL)
let configuration = ClassroomApplicationConfig(className: selectedClass, redirectUri: nil, authority: authority)
do {
return try ClassRoom(configuration: configuration)
} catch {
throw ServiceError.ClassroomApplicationCreation(error)
}
}
func findClassroom() throws -> String? {
guard
let selectedClass = UserDefaults.standard.string(forKey: selectedClass)
else {
throw ServiceError.ClassRoomSelectionError
}
do {
return try serviceManager.retrieveClassroom(selectedClass)
} catch {
throw ServiceError.ClassRoomSelectionError
}
}
Комментарии:
1. Почему нормально пересылать по инициализации полномочий, в то время как другие ошибки должны быть запутаны?
2. IMO, если ваш метод выдает ошибку, вы не должны перехватывать там ошибки. Просто выбросьте правильные ошибки из вашего метода findClassroom и инициализатора ClassRoom.
3. @LeoDabus, не могли бы вы привести пример?
4. Просто удалите
do catch
и выдайте ошибку из вашего инициализатора и из метода findClassroom5. Вы имеете в виду последнее
do catch
? На какой инициализатор вы ссылаетесь?
Ответ №1:
Вы можете провести рефакторинг, чтобы у вас не было никаких охранников или блоков do / catch:
func createClassroom() throws -> ClassRoom {
let selectedClass = try findClassroom()
let classURL = try makeClassURL(from: selectedClass)
let authority = try Authority(url: classURL)
let configuration = ClassroomApplicationConfig(classId: selectedClass.ID, redirectUri: nil, authority: authority)
return try makeClassRoom(from: configuration)
}
func findClassroom() throws -> String {
guard allIsWell else { throw ServiceError.ClassRoomSelectionError }
return ""
}
func makeClassURL(from string: String) throws -> URL {
guard let classURL = URL(string: string) else {
throw ServiceError.UserDoesNotExist
}
return classURL
}
func makeClassRoom(from configuration: ClassroomApplicationConfig) throws -> ClassRoom {
do {
return try ClassRoom(configuration: configuration)
} catch {
throw ServiceError.ClassroomApplicationCreation(error)
}
}
Ответ №2:
Предполагая ClassRoom(configuration: configuration)
, что выбрасывает .classroomApplicationCreation
и findClassroom
выбрасывает .classRoomSelectionError
при сбое и возвращает необязательный результат при успешном выполнении, код может быть сокращен до
enum ServiceError: Error {
case classroomApplicationCreation(Error)
case userDoesNotExist(Error)
case classRoomSelectionError
}
func createClassroom() throws -> ClassRoom {
let selectedClass = try findClassroom()
guard let classURL = URL(string: selectedClass) else {
throw ServiceError.userDoesNotExist
}
let authority = try Authority(url: classURL)
let configuration = ClassroomApplicationConfig(classId: selectedClass.ID, redirectUri: nil, authority: authority)
return try ClassRoom(configuration: configuration)
}
И тип возвращаемого значения должен быть ClassRoom
.
Комментарии:
1. У меня есть исправленный
findClassroom()
метод