[wip] Implement error handling using error-chain #332
Conversation
I'm not sure of the impact on performance - you may want to silently ignore errors in production to run faster. Also note that I haven't looked at amethyst itself yet - currently only the renderer builds. |
Seems it's not working very well with ECS. Could you look into that? |
Yes, at this point I'm just gathering opinions on the general strategy.
…On 4 Sep 2017 19:30, "Simon Rönnberg" ***@***.***> wrote:
Seems it's not working very well with ECS. Could you look into that?
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#332 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ABU-XlJr6S3ST4RPBM0j9kMFjC8y2Lkhks5sfEGvgaJpZM4PMBvh>
.
|
FWIW, I like it. |
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.
Looks quite informative! I like the approach. I can't merge this until at minimum CI passes, ideally I'd like this implemented for our other crates in this PR as well. Pinging @amethyst/engine-devs Is anyone opposed to this style of error management? Please leave a comment saying you're not if you are not so we don't just have total silence here.
@@ -1,5 +1,6 @@ | |||
//! Launches a new renderer window. | |||
|
|||
#[macro_use] extern crate error_chain; |
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.
Odd, I've been writing mine as
#[macro_use]
extern crate error_chain;
Is it documented anywhere what style these should be? I wasn't able to find documentation for this.
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.
Note: I'm not requesting this be changed I just want to know if I've been doing mine wrong.
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 typically have been doing it your way, but there are some merits to the one liner.
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 completely indifferent - I'll change to the amethyst standard :)
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.
Did you do cargo fmt
?
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.
Good stuff! Looks fine so far to me.
} | ||
|
||
quick_main!(run); |
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.
In the future we should replace this with main again: rust-lang/rust#43301
amethyst_renderer/src/error.rs
Outdated
error_chain! { | ||
errors { | ||
/// Failed to create a buffer. | ||
BufferCreation(e: gfx::buffer::CreationError) { |
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.
According to docs here
when you wrap another error (not a chain) you put it into foreign_links
block.
This will add From
implementations automatically.
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.
If you will wrap this chain in main crate you need to add it in links
block
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.
If you use foreign_links, you gain ergonomics, but lose the ability to control the description (description is forwarded from contained error). I'll implement it using foreign_links, but want to note the trade-off.
Thanks for the replies, I'll implement this for all the crates |
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 work! Here are few things a noticed after reading over it.
@@ -37,6 +37,7 @@ rayon = "0.8" | |||
serde = "1.0" | |||
serde_derive = "1.0" | |||
winit = "0.7" | |||
error-chain = "0.10" |
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.
There already is 0.11
btw
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.
ty
@@ -1,5 +1,6 @@ | |||
//! Launches a new renderer window. | |||
|
|||
#[macro_use] extern crate error_chain; |
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.
Did you do cargo fmt
?
} | ||
|
||
quick_main!(run); |
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.
Examples should, if possible, avoid macros IMO.
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.
quick_main! could easily be replaced with how it is recommended to be done: link
fn main() {
if let Err(ref e) = run() {
use std::io::Write;
let stderr = &mut ::std::io::stderr();
let errmsg = "Error writing to stderr";
writeln!(stderr, "error: {}", e).expect(errmsg);
for e in e.iter().skip(1) {
writeln!(stderr, "caused by: {}", e).expect(errmsg);
}
// The backtrace is not always generated. Try to run this example
// with `RUST_BACKTRACE=1`.
if let Some(backtrace) = e.backtrace() {
writeln!(stderr, "backtrace: {:?}", backtrace).expect(errmsg);
}
::std::process::exit(1);
}
}
use std::fmt::{Display, Formatter}; | ||
use std::fmt::Result as FmtResult; | ||
use std::result::Result as StdResult; | ||
|
||
use gfx; | ||
use gfx_core; |
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 not recommended error_chain usage. It is advised to use paths from root, i.e ::gfx_core::*
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.
However, if it works I don't see any problems.
@@ -65,6 +65,11 @@ | |||
#![deny(missing_docs)] | |||
#![doc(html_logo_url = "https://tinyurl.com/jtmm43a")] | |||
|
|||
// for error-chain | |||
#![recursion_limit="4096"] |
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.
Why have 4096 as the limit?
error_chain recommends 1024, and if I remember correctly, newer rust versions have this limit already set to 1024.
I was having some issues with maxing out recursion. It might have been
before they increased the limit, so I will check without the config line
before I say everything's ready for review.
…On Fri, Sep 8, 2017 at 12:43 PM, Emil Gardström ***@***.***> wrote:
***@***.**** commented on this pull request.
------------------------------
In amethyst_renderer/src/error.rs
<#332 (comment)>:
> @@ -1,126 +1,70 @@
//! Renderer error types.
-use std::error::Error as StdError;
-use std::fmt::{Display, Formatter};
-use std::fmt::Result as FmtResult;
-use std::result::Result as StdResult;
-
use gfx;
use gfx_core;
However, if it works I don't see any problems.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#332 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/ABU-XiY6bxFEd7stw_XenlYAwApNMx2Nks5sgSh0gaJpZM4PMBvh>
.
|
This feature becomes rather important as hierarchy of errors in amethyst grows. |
I'm currently trying to understand the asset loader, so I can do an error chain. I need to have a think, because at the moment errors are not concrete types. |
@derekdreery what do you mean? |
An example of a generic error would be #[derive(Clone, Debug)]
pub enum LoadError<A, F, S> {
/// The conversion from data -> asset failed.
AssetError(A),
/// The conversion from bytes -> data failed.
FormatError(F),
/// The storage was unable to retrieve the requested data.
StorageError(S),
} I'm still exploring where these are specialised into concrete types. If that's done in user code, it may be necessary to use trait objects. Another option would be to remove the generics from these errors, and let the user put anything implementing |
@derekdreery |
Out of 12 files changed 10 now have conflicts. It'd probably be easier to rewrite this PR rather than try and re-merge it at this point. If you disagree with me @derekdreery I'll re-open this but for now I'm closing it. For future PR authors: Large architecture overhauls that hit multiple function signatures and existing processes have to be completed quickly or they rapidly become changes to outdated code. This PR has been open for almost a month now. |
I agree. |
This PR demonstrates the kind of way you would use
error-chain
to handle errors, and replaces all calls to expect/unwrap in the code and examples. Where I've created new error names to catch errors that were previously panicking, I'm not sure I've picked the right name, or that I'm capturing the right data, but at least this PR gives you a sense of how error handling could work.It collects any errors in the parallel draw call into a vector.
The examples have been updated to use
quick_main
macro, which allows the "main" function to return aResult
. If you run withRUST_BACKTRACE=1 cargo run ...
, then whenever an error-chain error is created, a backtrace is attached, and reported if using quick_main.