Swiftyjson - Call Can Throw, But It Is Marked with 'Try' and the Error Is Not Handled

Call can throw, but it is not marked with 'try' and the error is not handled

SwiftyJSON's JSON(data:) can throw an exception so you have to mark it with try.

Strict solution:

.map { (data) in
do {
return try JSON(data: data)
}
catch {
fatalError("unable to convert data to JSON")
}
}

Loose solution:

.compactMap { try? JSON(data: $0) }

swiftyjson - Call can throw, but it is marked with 'try' and the error is not handled

You should wrap it into a do-catch block. In your case:

do {
let session = URLSession.shared.dataTask(with: url) {
(data, response, error) in
guard let data = data else {
print ("data was nil?")
return
}

let json = JSON(data: data)
print(json)
}
} catch let error as NSError {
// error
}

IOS: Call can throw, but is not marked with 'try' and the error is not handled

What you want to do is the following.

var json: [AnyHashable:Any]?

do {
json = try JSON(data: data)
} catch _ {
json = nil
}

What xcode is trying to say is that calling the JSON(data: data) can throw an error and you should put it inside a try-catch

Call can throw, but it is not marked with 'try' and the error is not handled / Initializer for conditional binding must have Optional type, not 'JSON'

It would seem that the JSON initialiser throws, so the compiler is telling you you need to handle this.

You are also trying to access local variables declare in the .success code block outside of that block, so they are unknown. You also have the wrong name for the id variable.

AF.request(URL_USER_ADD, method: .post, parameters: body, encoding: JSONEncoding.default, headers: header).responseJSON { (response) in

switch response.result {
case .success(let result):
if let json = result as? Data {
guard let data = response.data else { return }
do {
let json = try JSON(data: data)
let id = json["_id"].stringValue
let color = json["avatarColor"].stringValue
let avatarName = json["avatarName"].stringValue
let email = json["email"].stringValue
let name = json["name"].stringValue
UserDataService.instance.setUserData(id: id, color: avatarColor, avatarName: avatarName, email: email, name: name)
completion(true)
} catch {
print(error)
completion(false)
}
}

case .failure(let result):
completion(false)
debugPrint(response.result as Any)
}
}
}
}

As a point of style, a completion handler that simply returns true or false isn't particularly useful as it doesn't provide any information on what went wrong when false is returned, but since you mention a lesson, I will assume that this isn't your design choice.

Error Call can throw, but is not marked with 'try' and the error is not handled

Swift 2.0 introduces error handling. The error indicates that logInWithUsername:password: can potentially throw an error, and you must do something with that error. You have one of a few options:

Mark your checkUserCredentials() functional as throws and propagate the error to the caller:

func checkUserCredentials() throws -> Bool {
try PFUser.logInWithUsername(userName!, password: password!)

if (PFUser.currentUser() != nil) {
return true
}
return false
}

Use do/catch syntax to catch the potential error:

func checkUserCredentials() -> Bool {
do {
try PFUser.logInWithUsername(userName!, password: password!)
}
catch _ {
// Error handling
}

if (PFUser.currentUser() != nil) {
return true
}
return false
}

Use the try! keyword to have the program trap if an error is thrown, this is only appropriate if you know for a fact the function will never throw given the current circumstances - similar to using ! to force unwrap an optional (seems unlikely given the method name):

func checkUserCredentials() -> Bool {
try! PFUser.logInWithUsername(userName!, password: password!)

if (PFUser.currentUser() != nil) {
return true
}
return false
}

Swift 2: Call can throw, but it is not marked with 'try' and the error is not handled

You have to catch the error just as you're already doing for your save() call and since you're handling multiple errors here, you can try multiple calls sequentially in a single do-catch block, like so:

func deleteAccountDetail() {
let entityDescription = NSEntityDescription.entityForName("AccountDetail", inManagedObjectContext: Context!)
let request = NSFetchRequest()
request.entity = entityDescription

do {
let fetchedEntities = try self.Context!.executeFetchRequest(request) as! [AccountDetail]

for entity in fetchedEntities {
self.Context!.deleteObject(entity)
}

try self.Context!.save()
} catch {
print(error)
}
}

Or as @bames53 pointed out in the comments below, it is often better practice not to catch the error where it was thrown. You can mark the method as throws then try to call the method. For example:

func deleteAccountDetail() throws {
let entityDescription = NSEntityDescription.entityForName("AccountDetail", inManagedObjectContext: Context!)
let request = NSFetchRequest()

request.entity = entityDescription

let fetchedEntities = try Context.executeFetchRequest(request) as! [AccountDetail]

for entity in fetchedEntities {
self.Context!.deleteObject(entity)
}

try self.Context!.save()
}

Swift Call can throw, but it is not marked with 'try' and the error is not handled

In order to use the copyItemAtURL function, you can do one of three things.

1) Try/catch

do {
try NSFileManager.defaultManager.copyItemAtURL(sourceSqliteURLs[index], toURL: destSqliteURLs[index])
} catch {
print(error)
}

This is the standard error handling method. All your code would go inside the do block, including your try statement, and any errors would be handled in the catch block.

2) try!

try! NSFileManager.defaultManager()...

If an error is thrown with try! it will cause a runtime crash.

3) try?

 try? NSFileManager.defaultManager()...

Either the call will succeed or the result of the call will be nil. No errors thrown, no crash.

I would recommend you read the documentation, it's quite explicit about all this.

Swift: Extra argument 'error' in call

With Swift 2, the signature for NSJSONSerialization has changed, to conform to the new error handling system.

Here's an example of how to use it:

do {
if let jsonResult = try NSJSONSerialization.JSONObjectWithData(data, options: []) as? NSDictionary {
print(jsonResult)
}
} catch let error as NSError {
print(error.localizedDescription)
}

With Swift 3, the name of NSJSONSerialization and its methods have changed, according to the Swift API Design Guidelines.

Here's the same example:

do {
if let jsonResult = try JSONSerialization.jsonObject(with: data, options: []) as? [String:AnyObject] {
print(jsonResult)
}
} catch let error as NSError {
print(error.localizedDescription)
}


Related Topics



Leave a reply



Submit