-
Notifications
You must be signed in to change notification settings - Fork 567
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
Convert internal X11 errors to anyhow. #982
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.
Overall this does look like a good way to reduce boilerplate so I think it's worth trying out. The error story of druid-shell
is rather weak/new. This X11 stuff I wrote just a few weeks ago, and some of it I already reconsidered when working on some macOS changes. So the current state certainly isn't great.
Let's try out anyhow
and see how it goes. We can polish up this PR and have it merged.
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.
Looking better! I pointed out some remaining issues. Also please add a changelog entry under maintenance.
@@ -14,6 +14,7 @@ | |||
|
|||
//! X11 implementation of features at the application scope. | |||
|
|||
use anyhow::{anyhow, Context, 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.
Move this import lower next to xcb
.
The general grouping order of imports should be: std / external / crate / super / descendants.
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.
This is still there too.
druid-shell/src/platform/x11/mod.rs
Outdated
pub mod keycodes; | ||
pub mod menu; | ||
pub mod window; | ||
|
||
// TODO: This is just a placeholder, because we haven't removed all the other platform errors yet. |
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'm not sure that removing platform errors is the way forward. If you look at the Windows platform error code for example, it contains some rather useful HRESULT
handling.
Using anyhow
instead of Generic/Other
is fine. Using the new macros instead of BorrowError
is reasonable. However I think there's still room for platform specific errors that are specifically designed, like the Windows Error::Hr(HRESULT)
.
I'm open to hearing a good argument of course, but otherwise I think it makes sense to still have some X11 platform Error
type, even if really minimal.
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 could go either way on this, but let me explain my rationale anyway:
The only point (AFAICT) of having an error enum is to allow users to match on it, and I have trouble seeing a use-case for matching on a platform-specific error from druid-shell.
One reason for this is that druid-shell actually handles most of its own errors, because it's in charge of the run loop. I had a quick look through the API, and I only saw Application::new
and WindowBuilder::build
as places that the user gets an error.
The platform-specific nature of a platform error also makes me think that it's unlikely to be handled by the user, together with the fact that -- looking at the current set of errors -- I don't see what they would do with one besides logging it and exiting.
Having said that, anyhow::Error
does allow the user to get the underlying error if they really want it, because it supports downcasting. The main disadvantage compared to an error enum is ergonomics and discoverability.
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.
Not a lot of errors being surfaced outside of druid-shell
is more about it just not having been done yet. However I agree with your point that it's unlikely anyone will want to match against platform specific errors.
However the platform code itself might want to match against its own errors. Error handling isn't always going to be exactly where it happens.
Also the Windows Error::Hr(HRESULT)
continues to be very useful. There's no base error that can just be contexted. Thus I still don't see the platform specific Error
type going away.
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.
Fair enough; I've reinstated the X11 error module.
} | ||
} | ||
|
||
impl std::error::Error for 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 keep this impl line as well?
Sorry, I think I made a mistake with |
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.
Almost there!
Unfortunately the nightly compiler is breaking builds so we can't merge this yet. I opened #985 to address this, which is now merged. So you can rebase with master
to get the CI to pass.
@@ -143,6 +143,7 @@ This means that druid no longer requires cairo on macOS and uses Core Graphics i | |||
- Refactored DPI scaling. ([#904] by [@xStrom]) | |||
- Added docs generation testing for all features. ([#942] by [@xStrom]) | |||
- Renamed `BaseState` to `WidgetState` ([#969] by [@cmyr]) | |||
- X11: Reworked error handling ([#982] by [@jneem]) |
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.
Need to also add the link to the bottom of the 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.
I only skimmed this, due to a lack of time, but it looks like a nice change.
match borrow_mut!(self.handler) { | ||
Ok(mut handler) => { | ||
anim = handler.paint(&mut piet_ctx, invalid_rect); | ||
err = piet_ctx | ||
.finish() | ||
.map_err(|e| anyhow!("Window::render - piet finish failed: {}", e)); | ||
} | ||
Err(e) => { | ||
err = Err(e); | ||
let _ = piet_ctx.finish(); | ||
} | ||
}; |
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.
The second finish
call could fail as well, right? If we can add it to err
, than that would seem useful, otherwise we could just keep log
ing this 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.
The only way I can find to return a double error is context
, which isn't really appropriate IMO because it's for when one error is caused by another. I added a log, though.
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 your effort!
I think this is an improvement but I don't think adding a dependency is the best route long-term; in general I think that crates like anyhow make sense for applications, but less so for frameworks, where they can force downstream crates into a particular error handling path. There's some discussion of a longer-term error strategy somewhere; but basically I think that each platform should have an internal error type that closely matches whatever the native error type on that platform is, and then druid-shell should have a set of errors for common situations and then should also wrap the platform error type for more detail. |
I understand the usual dependency issues like compile time, quality issues etc. However when directly talking about the error types, I'm not sure I follow how What difference does it make if |
/bloat (curious to know if this works after merge?) To be fair I haven't read through this carefully, just trying to keep my head above water. I'm certainly happy for any improvements to error stuff in the short term. |
It doesn't seem to be doing much... Isn't bloat only for mac, though? Given that I didn't touch the mac backend, I wouldn't be surprised if whatever bloat I introduced just gets optimized out... |
yea apparently it won't work if something has been merged. And fair point, that will need reworking at some point. :) |
This isn't really a serious PR, but I wanted to discuss something along these lines. Trying to add present support for X11 Present, I had lots of
RefCell
borrowing and, as a result, hundreds of lines of error handling boilerplate. This is an attempt to reduce that.I'm not sure that adding a new dependency is the way to go, but I do think we want more ergonomic "generic" errors in druid-shell, particularly in the platform code. There are so many different errors that can come from the system, where it doesn't make sense to do much more than print a backtrace. Since many of these errors can never actually make it back to druid, it doesn't make much sense to have nice enums for them; that's why I thought of giving anyhow a try.