Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

255
Vistas
Do we always need to call a completion handler inside a closure?

I have a completion handler that gets called inside my closure. However, the completion handler only gets called when everything goes well. In the case of an error, the completion handler never gets called.

func product(with id: String, _ completion: @escaping (Product) -> ()) {

     // Make a network request for the product
     ...

    if (product) {
       completion(product)
    }
}

Is this a bad design? I recently got the comment that completion handlers need to be called even in case of errors, otherwise the caller will be waiting indefinitely. I've never heard that before and now I'm wondering if this applies to Swift.

over 4 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

Strictly spoken the caller doesn't wait at all. The code in the closure will or will not be executed.

However it's good practice to return errors, too.

A smart way is the Result type

func product(with id: String, completion: @escaping (Result<Product,Error>) -> Void) {

     // Make a network request for the product
     ...
    if error = error { completion(.failure(error)); return }

    if product {
       completion(.success(product))
    } else {
       let error = // create some other error
       completion(.failure(error))
    }
}

And call it

product(with: "Foo") { result in
   switch result {
     case .success(let product): // do something with the product
     case .failure(let error): // do something with the error
   }
}

Note: The underscore character before completion in the function declaration is pointless.

over 4 years ago · Santiago Trujillo Denunciar

0

If you will not call a completion nothing will happen 'cuz completion caller will not wait for it.

But if you want to cover all cases try to add a failure callback. For example:

func product(with id: String, _ success: @escaping (Product) -> (), failure: @escaping (Any) -> ())
over 4 years ago · Santiago Trujillo Denunciar

0

In your case, if you are treating it as a completion, it means that it has to get called no matter what's case (success of failure with error), it has to returns when the process completed.

What you could do is to pass an optional error and product to the completion closure and then check whether the error is nil or not:

func product(with id: String, _ completion: @escaping (Product?, Error?) -> ()) {
    // in case of there is an error:
    completion(nil, error)
    return

    // if things went happy:
    completion(product, nil)
}

Calling the method:

product(with: "ID") { (product, error) in
    guard let returnedError = error else {
        print(product)

        return
    }

    print(returnedError)
}

Or:

product(with: "ID") { (product, error) in
    if let returnedError = error {
        print(returnedError)
        return
    }

    print(product)
}
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda