0

I am writing a closure with error handling, but I am getting a warning "'catch' block is unreachable because no errors are thrown in 'do' block" in the catch line. This is my code:

class Service {
func graphQL(body: [String:Any], onSuccess: @escaping (Foundation.Data) -> (), onFailure: @escaping (Error) -> ()) {
    var request = URLRequest(url: url)
    
    request.httpMethod = "POST"
    request.setValue("application/json", forHTTPHeaderField: "Content-Type")

    request.httpBody = try? JSONSerialization.data(withJSONObject: body, options: .fragmentsAllowed)
    
    URLSession.shared.dataTask(with: request) { (data, response, error) in
        if let error = error {
            onFailure(error)
        }

        if let data = data {
            do{
                onSuccess(data)
            }
            catch{
                onFailure(error)
            }
        }
    }.resume()
}


class TimeDepositManager {
func getTimeDeposits(onSuccess: @escaping ([TimeDeposits]) -> (), onFailure: @escaping (Error) -> ()) {
    let body = ["query": "{ account { timeDeposits { returnAmount interestRate dueDate originalAmount id startDate currency } } }"
    ]

    Service().graphQL(body: body, onSuccess: { data in
        let json = try? JSONDecoder().decode(GraphQLResponse.self, from: data)
        onSuccess(json?.data?.account?.timeDeposits ?? [])
    }, onFailure: { error in
        print(error)
    })
}

I want the logic of onSuccess in the func getTimeDeposits(), but how remove this catch block warning?

akitainu22
  • 95
  • 1
  • 8
  • Remove the do/catch to remove the warning because you can only use that when you have a function that is declared to throw, you want an if/else instead. – Joakim Danielson Nov 25 '21 at 20:38
  • Not related to your question but looks like you have created a custom struct and named it `Data`. You should choose another name for your structure – Leo Dabus Nov 25 '21 at 22:20

2 Answers2

2

Swift requires some "expectations" when it comes to error handling.

That is, success needs to declare that it can throw an error (based on my understand of your requirements), for example

func graphQL(body: [String:Any], onSuccess: @escaping (Foundation.Data) throws -> (), onFailure: @escaping (Error) -> ()) {

And then you will need to try and call success...

do{
    try onSuccess(data)
}
catch{
    onFailure(error)
}
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
1

how remove this catch block warning?

By removing the do-catch block entirely because there is nothing which throws

Replace

URLSession.shared.dataTask(with: request) { (data, response, error) in
        if let error = error {
            onFailure(error)
        }

        if let data = data {
            do{
                onSuccess(data)
            }
            catch{
                onFailure(error)
            }
        }
    }.resume()

with

URLSession.shared.dataTask(with: request) { (data, _, error) in
        if let error = error {
            onFailure(error)
        } else {
            onSuccess(data!)
        }
    }.resume()

Side note: Rather than very cumbersome and dated

onSuccess: @escaping (Foundation.Data) -> (), onFailure: @escaping (Error) -> ())

consider to use the Result type

completion: @escaping (Result<Data,Error>) -> Void)
vadian
  • 274,689
  • 30
  • 353
  • 361