Понимание обработки ошибок с помощью CoreData - PullRequest
0 голосов
/ 18 июня 2020

У меня есть сценарий, в котором я ожидаю, что что-то произойдет, но этого не происходит, и я не могу понять, почему. Я все еще новичок в метательных функциях, поэтому мне здесь немного любопытно. Может быть, кто-нибудь сможет объяснить, почему это произошло.

Я сделал эту функцию:

func checkExistanceOfMovieAddition(id: Int) -> Result<SavedMovieAddition, CoreDataErrors> {
    let request: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest(entityName: SavedMovieAddition.entityName)
    request.predicate = NSPredicate(format: "movieID == \(id)")

    do {
        let fetch = try context.fetch(request)
        if let result = fetch.first as? SavedMovieAddition {
            return.success(result)
        } else {
            return.failure(.additionNotFound)
        }
    } catch {
        return.failure(.fetchFailed)
    }
}

И она работает как шарм. Если я ищу идентификатор, который не существует, я получаю пустой массив и возвращаю свой собственный тип ошибки. Однако ... если я изменю строку:

request.predicate = NSPredicate(format: "movieID == \(id)")

и неправильно напишу «movieID» на «movieIDs», которого нет в моей модели CoreData, приложение выйдет из строя с:

Thread 1: Exception: "keypath movieIDs not found in entity <NSSQLEntity SavedMovieAddition id=2>"

Здесь Я ожидал, что он go блок catch и вернет .fetchFailed?

Почему этого не происходит? Но вместо этого приложение вылетает? - Я думал, что весь смысл блока do-try-catch состоит в том, чтобы устранить эти сбои?

Что-то мне не хватает?

1 Ответ

0 голосов
/ 19 июня 2020

Вы получили несколько комментариев с хорошими пояснениями. Еще одна вещь, которая может быть полезна, заключается в том, что вы можете помочь избежать описываемой вами ошибки, не используя пустые строки, если вы можете их избежать. По возможности сделайте что-нибудь, что позволит компилятору проверить, нет ли у вас ошибок. В этом случае помогут пути к клавишам Swift.

У вас есть

request.predicate = NSPredicate(format: "movieID == \(id)")

... который работает, но если вы неправильно написали свойство, это может стать проблемой. Если вы напишете это как

request.predicate = `NSPredicate(format: "\(#keyPath(SavedMovieAddition.movieID)) == \(id)")`

... путь ключа будет проверен компилятором. Если вы наберете его как movieIDs, ваш код не будет компилироваться и вы получите сообщение об ошибке Type 'SavedMovieAddition' has no member 'movieIDs'. Вы также можете написать это так, если это имеет для вас больше смысла:

request.predicate = `NSPredicate(format: "%K == \(id)", #keyPath(SavedMovieAddition.movieID))`
...