Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift 5.5 Concurrency: creating a task with custom error type

I need to use my own custom error enum in tasks that I create:

enum MyError: Error {
 case someError
}

var myTask: Task<MyModel, MyError> = Task { () throws -> MyModel in
            // in case of an error: 
            // throw .someError
            // ... perform some work
            return MyModel()
        }

but I got the following error at the beginning of Task initializer: Referencing initializer 'init(priority:operation:)' on 'Task' requires the types 'MyError' and 'Error' be equivalent.

How can I restrict the Task to only throw errors that are of my custom error type MyError ?

like image 731
JAHelia Avatar asked Mar 02 '23 11:03

JAHelia


1 Answers

Omit the unnecessary type declaration:

var myTask = Task { () throws -> MyModel in
    // in case of an error:
    throw MyError.someError
    // ... perform some work
    return MyModel()
}

The compiler implicitly (and rightly) types myTask as a Task<MyModel, Error>. The compiler doesn't care that what you throw is a MyError, because that's a form of Error.


Okay, I see now that the issue is merely that you asked the wrong question. You want to know why you can't declare this Task as a Task<MyModel,MyError>.

The reason is because of how this initializer is declared:

extension Task where Failure == Error {
    public init(priority: TaskPriority? = nil, operation: @escaping @Sendable () async throws -> Success)
}

Do you see? This initializer is available only where Failure == Error. That's ==, not :. Using this initializer doesn't require that the Failure type be an Error, it requires that it be Error.

like image 156
matt Avatar answered Mar 15 '23 23:03

matt