Function declarations must always explicitly specify whether they throw, optionally providing a specific thrown error type.
// For Functions expressions, these are equivalent.
func throwCallBack(callback: () throws -> Void) throws {}
func throwCallBack<E: Error>(callback: () throws(E) -> Void) throws(E) {}
// In your case, If you wanna a typed throws function, it should be like:
func throwCallBack(callback: () throws(SomeError) -> Void) throws(SomeError) {}
// For Closures expressions are like:
{ () -> Bool in true }
{ () throws -> Bool in true }
{ () throws(CatError) -> Bool in true }
But there's some specified rules for inferring the error types.
With typed throws, the closure type could be inferred to have a typed error by considering all of the throwing sites that aren't caught (let each have a thrown type Ei) and then inferring the closure's thrown error type to be errorUnion(E1, E2, ... EN).
Swift 6: This inference rule will change the thrown error types of existing closures that throw concrete types. For example, the following closure:
will currently be inferred as throws. With the rule specified here, it will be inferred as throws(CatError). This could break some code that depends on the precisely inferred type. To prevent this from becoming a source compatibility problem, we apply the same rule as for do...catch statements to limit inference: throw statements within the closure body are treated as having the type any Error in Swift 5. This way, one can only infer a more specific thrown error type in a closure when the try operations are calling functions that make use of typed errors.
Note that one can explicitly specify the thrown error type of a closure to disable this type inference, which has the nice effect of also providing a contextual type for throw statements:
{ () throws(CatError) in if Int.random(in: 0..<24) < 20 { throw .asleep } }