I'm in favor of these directives, but I would go the #directive(...)
route from the beginning. Here is why I think we should use the approach from the alternatives rather than the proposed one:
-
At least for
#warning
directive I think it doesn't have to be a compile time only warning. Similar to how thread sanitizer in Xcode emits warnings at runtime, I think we should also be able to emit runtime warnings in our projects if at runtime something unexpected happened. Ideally this is a better way to log issues during development and testing, where I'd also assume that the warning is removed by the compiler for a release build automatically.-
#warning("....")
is the same as#warning("....", at: .compiletime)
- Additionally we'd have
#warning("...", at: .runtime)
-
Here is a small peace of code that I took from my current project, where I could make use of a runtime warning rather than printing the issue and filtering all logs to find it.
private func on<TriggerObservable>(
completable: Completable,
handleError: ErrorHandler<TriggerObservable>? = nil,
recover: RecoveryHandler? = nil,
complete: CompletionHandler? = nil,
dispose key: UnleashedDisposeKey
) where TriggerObservable : ObservableType {
var completable = completable
// Add error handler if needed
if let handleError = handleError {
completable = completable.retryWhen(handleError)
}
let dispose: () -> Void = { self.disposeCache[key] = nil }
let recoverAndDispose: RecoveryHandler = { error in
if let recover = recover {
DispatchQueue.main.async { recover(error) }
} else {
#warning("""
Unhandled error 🆘:
- \(error)
- Emitted on a completable sequence\n
""", at: .runtime)
)
}
dispose()
}
let completeAndDispose: CompletionHandler = {
if let complete = complete {
DispatchQueue.main.async(execute: complete)
}
dispose()
}
completable
.subscribe(onCompleted: completeAndDispose, onError: recoverAndDispose)
.disposed(by: disposeCache, key: key)
}
The issue here is that the error handling in implemented in a different place and simply cannot be included into the else
branch of the if statement. Rather than printing the warning, I'd love to see the warnings emitted by the IDE which would provide me an easy way to jump to the source code that emitted the warning and also show more informations defined in the custom string.
I also have a few questions related to #warning
:
- Are the emitted warnings bound to a module?
- If not, how can we mute those warnings emitted by an integrated 3rd party module?
EDIT:
-
Only runtime warnings can have string interpolations, build-time warnings must be composed out of a constant string (single or multi-lined version are both allowed).
-
We could also allow for symmetrical consistency runtime errors which will behave as a simple wrapper over
fatalError
.