Method to generate error (failure) for a SwiftUI Combine publisher

Viewed 820

I'm writing a Mock service to test login in a SwiftUI MVVM project. In my ViewModel:

  func login() {
    self.cancellable = service.login(email: email, password: password)
      .sink(receiveCompletion: { [weak self] completion in
        switch completion {
          case .finished:
            break
          case .failure(let error):
            if let session = self?.session {
              session.currentUser = nil
            }
            print(error.localizedDescription)
        }
      }, receiveValue: { user in
        if let session = self.session {
          session.currentUser = user
        } 
      })
  }

My mock service code:

func login(email: String, password: String) -> AnyPublisher<User, Error> {
    
    let user = User(name: "test", email: email, password: password)
    if email.lowercased() == "test@mail.com" && password == "Password!23" {
      return Just(user)
        .setFailureType(to: Error.self)
        .eraseToAnyPublisher()
    } else {
      // ??? How to generate a failure here
    }
  }

My question is how to generate an error (failure) in my code? I only found some code sample regarding with error handling. But can't find how to generate an error in publisher.

1 Answers

There's an Fail Combine publisher that does exactly what you're after:

extension String: Error {}

func randomlyFail() -> AnyPublisher<Int, Error> {
   Bool.random()
    ? Fail(error: "random error")
        .eraseToAnyPublisher()
    : Just(1)
        .setFailureType(to: Error.self)
        .eraseToAnyPublisher()
}
Related