-
Notifications
You must be signed in to change notification settings - Fork 645
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
addition of assertSuccess() and assertFailure() on EventLoopFuture #2417
addition of assertSuccess() and assertFailure() on EventLoopFuture #2417
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for this! I am inclined to want to say that these methods do slightly too much. Having the callback as an argument muddys the water about their actual semantic. If these methods instead behave like a regular future function (where they return a new future) then we can allow them to compose with the rest of the future handling functions, which might be nicer.
@weissi I'm also curious whether you think assertion is sufficient, or whether we need precondition variants too.
Agreed!
I'd think we should have both |
37fe5c5
to
ac4ea51
Compare
Added |
case .success(let value): | ||
promise.succeed(value) | ||
case .failure(let error): | ||
assertionFailure("Expected success, but got failure: \(error)") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we pass file
and line
through from the line that calls assertSuccess
? That'll make the crash more generally useful.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh sorry, you already commented with that. Please ignore my extra SPAM 🙈
self.whenComplete { result in | ||
switch result { | ||
case .success(let value): | ||
assertionFailure("Expected failure, but got success: \(value)") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same note here on file
and line
.
/// | ||
/// If the original future fails, it triggers a precondition failure, causing a runtime error during development. | ||
@inlinable | ||
public func ensureSuccess() -> EventLoopFuture<Value> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think using precondition
instead of ensure
on these two methods is better, as it fits with our existing prior art.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I ran into an issue where preconditionFailure
as the method name conflicts with the global preconditionFailure function in Swift, i could rename it to be something like preconditionOnSuccess
potentially?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can disambiguate by using Swift.preconditionFailure(...)
to refer to the global one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good making the changes!
case .success(let value): | ||
promise.succeed(value) | ||
case .failure(let error): | ||
preconditionFailure("Expected success, but got failure: \(error)") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we pass file
and line
through?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes to all!
self.whenComplete { result in | ||
switch result { | ||
case .success(let value): | ||
preconditionFailure("Expected failure, but got success: \(value)") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we pass file
and line
through?
/// If the original future fails, it triggers an assertion failure, causing a runtime error during development. | ||
@inlinable | ||
public func assertSuccess() -> EventLoopFuture<Value> { | ||
let promise = self.eventLoop.makePromise(of: Value.self) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to create a promise in any of these functions; you can use always
instead:
return self.always { result in
switch result {
case .success:
()
case .failure(let error):
assertionFailure("Expected success, but got failure: \(error)")
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed, but we should pass file
and line
to assertionFailure
such that it shows where the user put .assertX
and not always this line
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh okay i see no need to create a new promise / or complete it bc always
can take care of that for us, working on the changes. Thank you!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
changes commited!
/// | ||
/// If the original future fails, it triggers a precondition failure, causing a runtime error during development. | ||
@inlinable | ||
public func ensureSuccess() -> EventLoopFuture<Value> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can disambiguate by using Swift.preconditionFailure(...)
to refer to the global one.
/// | ||
/// If the original future fails, it triggers an assertion failure, causing a runtime error during development. | ||
@inlinable | ||
public func assertSuccess() -> EventLoopFuture<Value> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
here and in the other functions we should take file: ... = #file, line = ... #line
and pass that to the (assertion/precondition)Failure functions
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please use #fileID
and not #file
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done to all!
…tps://github.com/dkz2/swift-nio into dkz2-EventLoopFuture-assertSuccess-assertFailure
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice one, this LGTM.
@swift-server-bot test this please |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for taking care of this!
Added
assertSuccess
,assertFailure
,preconditionSuccess
andpreconditionFailure
methods toEventLoopFuture
for safer and more explicit error handling.Motivation:
Enhance developer experience by providing a clear way to handle expected success or failure of futures.
Closes #2359.
Modifications:
Implemented
assertSuccess
,assertFailure
,preconditionSuccess
andpreconditionFailure
forEventLoopFuture
.Added corresponding test cases to verify behavior of the new methods.
Result:
Developers will now have access to
assertSuccess
,assertFailure
,preconditionSuccess
andpreconditionFailure
methods onEventLoopFuture
.