Giter Club home page Giter Club logo

error-chain's People

Contributors

ahmedcharles avatar ajdlinux avatar andygauge avatar birkenfeld avatar brson avatar budziq avatar cramertj avatar dead10ck avatar debris avatar eddyb avatar ehuss avatar faern avatar golddranks avatar guillaumegomez avatar joshtriplett avatar kodraus avatar kw217 avatar lukaskalbertodt avatar mathstuf avatar mre avatar nelsonjchen avatar palfrey avatar prekucki avatar sfackler avatar sgrif avatar sourcefrog avatar tinaun avatar tworec avatar untitaker avatar yamakaky avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

error-chain's Issues

Does this library allocate?

I'm wondering if this is suitable for representing errors in a potential out-of-memory condition (i.e. malloc failure)?

Please support older versions of Rust

I'd like to use error-chain as part of the dependencies for a project, but that project needs to support Rust 1.10. error-chain uses the ability to put attributes on non-item statements and expressions, specifically to handle the backtrace feature. Please consider moving those attributes upward (even though it duplicates a bit more code), to allow error-chain to build and run on Rust 1.10.

Please remove the executable bit from tests/tests.rs

tests/tests.rs has the executable bit set, and happens to start with #! (as part of a Rust directive), which makes it look like a script with the very strange interpreter [allow(dead_code)]. This confuses the Debian packaging lint tool "lintian", which then has various gripes about how strange that interpreter looks. Can you please remove the executable bit?

Why does extract_backtrace return Option<Option<BT>> instead of Option<BT> ?

If underlying error has None backtrace for any reason, the chained error will not get backtrace either - extract_backtrace will return Some(None) so State::backtrace will be None, and cycle will repeat again.

It seems to me it would be better if it was just Option<BT>, and the impl returned just e.state.backtrace.clone()

Problems with foreign_links

First of all, it seems that the order of the blocks in error_chain! { } matters (placing foreign_links after errors made it break). This feels different from the general top-level declarations in Rust so I was surprised. Can the macro be made flexible about the order of the declarations?

Secondly, and more importantly, I'm still unable to get it work :( I have code like this:

pub mod errors {
    error_chain! {
        foreign_links {
            diesel::result::Error, DieselError;
        }
        errors {
            NoSuchUser(email: String) {
                description("No such user exists")
                display("No user with e-mail address {} exists.", email)
            }
            EmailAddressTooLong {
                description("E-mail address too long")
                display("A valid e-mail address can be 254 characters at maximum.")
            }
            AuthError {
                description("Can't authenticate user")
                display("Username (= e-mail) or password doesn't match.")
            }
        }
    }
}

use errors::*;

The foreign links section breaks:

error[E0433]: failed to resolve. Use of undeclared type or module `diesel::result`
  --> src/lib.rs:29:13
   |
29 |             diesel::result::Error, DieselError;
   |             ^^^^^^^^^^^^^^^^^^^^^ Use of undeclared type or module `diesel::result`
<error_chain macros>:119:1: 124:37 note: in this expansion of error_chain! (defined in <error_chain macros>)
<error_chain macros>:133:1: 138:37 note: in this expansion of error_chain! (defined in <error_chain macros>)
src/lib.rs:27:5: 61:6 note: in this expansion of error_chain! (defined in <error_chain macros>)

But I have extern crate diesel; in place, so fully qualified paths starting with diesel should work, right? And trying to address the error message with use diesel::result; or use diesel::result::Error; doesn't help. What to do?

infer the `ErrorKind` - e.g. via an associated type of some trait :-)

Motivation

I think one could simplify the link definitions:

    links {
        rustup_dist::Error, rustup_dist::ErrorKind, Dist;
    }

to something like this

    links {
        rustup_dist::Error, Dist;
    }

Possible Solution

To achieve this, rustup_dist::Error could implement something like trait ErrorChain { type ErrorKind: StdError + Debug; }. If this trait is in scope, the associated type could be queried via rustup_dist::Error::ErrorKind and does not need to be set explicitly. I think this would allow a more comfortable API.

Drawbacks

  • There is already a ChainErr trait. A similar named trait could lead to some confusion.

Alternative

Alternatively, the compound error could just be a type-alias for a specific variant of a generic struct. I.e.

  • macro defines pub enum $error_kind_name { /* ... */ }
  • macro also defines type $error_name = ErrorChain<$error_kind_name>;
  • the error-chain crates defines the generic struct pub struct ErrorChain<ErrorKind: StdError + Debug> ( /* ... */ );

The effect should roughly be the same - the link definition would then include the ErrorKind instead.

    links {
        rustup_dist::ErrorKind, Dist;
    }

Add helpers to implement main()

https://brson.github.io/2016/11/30/starting-with-error-chain provides a great template for main(), delegating to a function that can return a Result. And I agree that almost all main() functions should look like that. So, I'd love to have some helper methods for that pattern, to avoid duplicating that code across every application using error-chain.

I'd suggest two helper methods: one that prints the error, causes, and possible backtrace, and one that calls that method and then ::std::process::exit(1). The former would help for projects that run individual commands/requests and want to thoroughly report errors for each without exiting on failure; the latter would work for all simple command-line tools that want to exit if the top-level main-equivalent returns an error.

With the latter, the template main could look something like this:

fn main() {
    real_main().toplevel_unwrap();
}

backtrace as optional feature

Would it be possible to make backtrace support optional?
It brings in dependency on dbghelp and consecutively does not work on WinXP/2003.

Using ChainedError generically

Hey there, I'm writing another library, which needs users to be able to define their own errors and compose them with other users' error types. I was hoping simply requring users to define their errors with error-chain would solve this problem, but I'm having some trouble.

Specifically, I'd like:

  1. E: ChainedError gives me a way of performing a conversion for<F: ChainedError> F => E. That is, I can convert any ChainedError into any other ChainedError. Though the library may generate specific impls that enable this (seems like the ResultExt does this), there's no trait abstraction of this operation allowing me to deploy it in a generic context.
  2. The same thing, but for<F: std::error::Error> F => E. That is, I can convert any Error into any ChainedError. This may be trickier, of course, because it may require creating a Box<Error>, and may be less preferential than explicit links for this reason (though I sort of don't agree that avoiding dynamic dispatch in the error path is significantly beneficial).

Is it possible for either of these to be provided? Unfortunately orphan rules prevent any impl of From<X> for T: ChainedError, and without HRTB of types you can't bound ChainedError: for<X> From<X> either. But even if I had to be explicit, that would be better than being unable to do it.

Allow the 'types' section of the macro to be empty

Right now in types { } you are forced to write 4 type names. I did this because I assumed hygiene wouldn't let me fabricate those names into the surrounding scope, but this is not true.

If this section is empty the macro should just use the conventional names.

Error links cause conflicting From implementations when used cross-crate

I have this minimal repository that reproduces the issue: https://github.com/dflemstr/error-chain-test

Running cargo build in the b directory yields:

$ cargo build
   Compiling b v0.1.0 (file:///home/dflemstr/github.com/dflemstr/error-chain-test/b)
error[E0119]: conflicting implementations of trait `std::convert::From<ErrorKind>` for type `ErrorKind`:
 --> src/lib.rs:5:1
  |
5 | error_chain! {
  | ^
  |
  = note: conflicting implementation in crate `core`
  = note: this error originates in a macro outside of the current crate

error: aborting due to previous error

error: Could not compile `b`.

To learn more, run the command again with --verbose.

Clippy warning

warning: redundant closure found, #[warn(redundant_closure)] on by default
  --> src/types/decode.rs:5:1
   |
5  | error_chain! {
   | ^
   |
help: remove closure as shown:
   | . unwrap_or_else ( $ crate :: make_backtrace ) ; $ error_name (
   = help: for further information visit https://github.com/Manishearth/rust-clippy/wiki\#redundant_closure
   = note: this error originates in a macro outside of the current crate

Seems to be https://github.com/brson/error-chain/blob/master/src/lib.rs#L503, but I can't find why...

Numerous tests don't set ResultExt in types{} correctly

Consider adding support for Futures crate

I've been playing around with Futures and Tokio lately, and one of the things that's been a major pain point has been dealing with errors from Futures. I think it would be really nice to be able to call chain_err on a Future. Currently, the Future trait defines a map_err function, which isn't to terribly far off. It's just a lot more verbose since the conversion between error types has to be done manually. Any thoughts?

Add Optional error codes to identify errors

Hi,

When interacting rust code with other languages, we can't do pattern matching on error types.
As a consequence being able to add a method to define error code according of the type of the error would be great.

Thank you

Display implementation should show the error's Display, not just the description

Given the following invocation of error_chain!:

error_chain! {
    types {
        Error, ErrorKind, ChainErr, Result;
    }
    links {}
    foreign_links {
        git2::Error, Git2, "git error";
    }
    errors {
    }
}

Producing an error from a git2::Error and then printing that error just produces "git error", without actually printing the underlying git2::Error. The Display implementation for an error produced from a foreign link should forward to the Display implementation for the linked error.

Foreign error links lose type information

If I have a:

error_chain! {
    links {
        rustup_dist::Error, rustup_dist::ErrorKind, Dist;
        rustup_utils::Error, rustup_utils::ErrorKind, Utils;
    }
}

...and I do:

let e: Error = Error::from(rustup_dist::Error::Foo)

Then there is no way for me to get back a rustup_dist::Error instance from e that would let me determine whether it is a rustup_dist::Error::Foo.

I don't know if it's a good idea, but maybe ErrorKind::Dist could contain a type safe reference to the cause, and not have a boxed cause for that case?

Custom result type necessary?

I've been working on moving my library from Results througout towards the glorious future of Futures throughout.

That means that error_chain now produces a lot for dead weight for me, especially a Result sugar I don't use anymore.

Before futures, errors where de-facto coupled to results. Now, they are becoming the glue between futures, results and possibly other abstractions in the future. I think error_chain should stop worrying about results too much and concentrate on the error part.

Confusion/ergonomics problem with type inference and try!() or ?

Sometimes I want not to chain errors, but replace an error with another (in this case I don't want to leak information of what caused the AuthError). Trying to use map_err() for this, I run into problems with type inference.

pub fn auth_user(conn : &PgConnection, email : &str, plaintext_pw : &str) -> Result<User> {
    let (user, hashed_pw_from_db) = get_user_pass_by_email(conn, email)
                                .map_err(|_| ErrorKind::AuthError.into())?;
    let _ = password::check_password(plaintext_pw, hashed_pw_from_db.into())
                                .map_err(|_| ErrorKind::AuthError.into())?;
    Ok(user)

with code like this, I suspect that the type inference is not decidable:

error[E0282]: unable to infer enough type information about `_`
   --> src/lib.rs:140:37
    |
140 |     let (user, hashed_pw_from_db) = get_user_pass_by_email(conn, email)
    |                                     ^ cannot infer type for `_`
    |
    = note: type annotations or generic parameter binding required

I think this is because this code contains two nested .into()s, ErrorKind → Error, and then inside the ? operator. With two .into(), the types contain too much degrees of freedom to be inferable.

It's maybe because I'm a newbie, but it took me a LOT of fumbling to get the type annotations right:

pub fn auth_user(conn : &PgConnection, email : &str, plaintext_pw : &str) -> Result<User> {
    let (user, hashed_pw_from_db) = get_user_pass_by_email(conn, email)
                                .map_err::<Error, _>(|_| ErrorKind::AuthError.into())?;
    let _ = password::check_password(plaintext_pw, hashed_pw_from_db.into())
                                .map_err::<Error, _>(|_| ErrorKind::AuthError.into())?;
    Ok(user)
}

Then it occurred to me that since .into()ing ErrorKind → Error is a SUPER-common operation in error_chain, it would benefit the type inference if there were a non-generic function to do just that. I think it would help the type inference in many situations where more than one .into() would make the inference undecidable.

`Send` not implemented when using foreign link to `reqwest::Error`

$ rustc --version
rustc 1.15.0-nightly (daf8c1dfc 2016-12-05)
$ rg "error-chain" Cargo.toml
7:error-chain = "0.7.1"

I'm not sure if I should be filing this here, or in reqwest, but I'm getting an error about "std::error::Error + 'static: std::marker::Send is not satisfied" when trying to foreign link to reqwest::Error. I have an example project showing the issue here: https://github.com/pwoolcoc/reqwest-error-chain-test and the full error message is below.

> cargo build
   Compiling reqwest-error v0.1.0 (file:///home/paul/code/reqwest-error)
error[E0277]: the trait bound `std::error::Error + 'static: std::marker::Send` is not satisfied
 --> src/lib.rs:5:5
  |
5 |       error_chain!{
  |  _____^ starting here...
6 | |         foreign_links {
7 | |             ReqwestError(::reqwest::Error);
8 | |         }
9 | |     }
  | |_____^ ...ending here: the trait `std::marker::Send` is not implemented for `std::error::Error + 'static`
  |
  = note: `std::error::Error + 'static` cannot be sent between threads safely
  = note: required because it appears within the type `Box<std::error::Error + 'static>`
  = note: required because it appears within the type `reqwest::Error`
  = note: required because it appears within the type `errors::ErrorKind`
  = note: required because it appears within the type `errors::Error`
  = note: required by `error_chain::ChainedError`
  = note: this error originates in a macro outside of the current crate

error: aborting due to previous error

error: Could not compile `reqwest-error`.

To learn more, run the command again with --verbose.

Another usability issue with map_err

Sometimes I want not just chain errors, but "semi-handle" them: check the result, maybe handle or "decorate" one possible error and still pass theResult downstream.

.map_err() allows me to inspect the error, have my way with it and then continue, but the API of error_chain could do a lot better to help with this. Here's the problem: it seems that you can only chain errors (box and store the earlier error as the cause) with .chain_err, and that only works with Results. But inside a .map_err() we are dealing directly with some error values. This leads to this monstrosity, where I first match on the foreign ErrorKind, then wrap it again in an Result::Err variant (+ work around inference issues), pass that to the chain_err() and then unwrap that to return from the .map_err().

users::table
    .inner_join(passwords::table)
    .filter(users::email.eq(user_email))
    .first(&*conn)
    .map_err(|e| match e {
            e @ NotFound => Err::<(), diesel::result::Error>(e).chain_err(|| ErrorKind::NoSuchUser(user_email.into())).unwrap_err(),
            e => Err::<(), diesel::result::Error>(e).chain_err(|| "Error when trying to retrieve user!").unwrap_err(),
    })

If there were a version of chain_err() that worked directly with values, not with Result containers, it would help a lot:

users::table
    .inner_join(passwords::table)
    .filter(users::email.eq(user_email))
    .first(&*conn)
    .map_err(|e| match e {
            e @ NotFound => e.caused_err(|| ErrorKind::NoSuchUser(user_email.into())),
            e => e.caused_err(|| "Error when trying to retrieve user!"),
    })

Am I missing something really obvious or does this make sense?

add minimum supported version to Travis

So I know a lot of people use the nightly and a lot of people always run the latest stable rust. But there's some of us out there that will get stuck on a stable release for a few months due complexities in build environments, breakages moving forward, etc.

For all my crates I try to include the following in .travis-ci.yml so that there's a minimum supported version:

rust:
- nightly
- beta
- stable
- 1.4.0

Its fine to raise that level up as needed but its helpful to ensure that a "stable" series (e.g. 0.6.x) remains compatible with the same version of Rust or if it needs to be bumped up people can understand how they need to update.

Memory bloat

The code (basing on the example from the readme)

#![recursion_limit = "1024"]
#[macro_use]
extern crate error_chain;

mod errors {
    error_chain! { }
}

fn main () {
    use errors::Result as ChainResult;
    use std::mem::size_of;
    println!("size of vanilla result {}", size_of::<Result<(), ()>>());
    println!("size of error_chain result {}", size_of::<ChainResult<()>>());
}

outputs:

size of vanilla result 1
size of error_chain result 56

I might be wrong, but isn't ChainResult just "yet another enum", which means those 55 extra bytes have to be copied over when returning, even in the success event? That would mean quite a performance overhead over normal Result in hot code, especially where only the Ok case which may be minimal is encountered, no?

Maybe the situation can be improved by making the backtrace functionality optional, as in possible to opt out of at compile time?

Conditionnal compilation

It would be cool to support things like this (pseudo-code):

mod pote {
    error_chain! {
        errors {
            #[cfg(unix)]
            Unix {
            }
            #[cfg(not(unix))]
            Other {
            }
        }
    }
}

Currently, it works partially: the ErrorKind variant is generated correctly, but the matches always use the variants. Places which should be modified:

  • impl Debug for ErrorKind
  • impl Display for ErrorKind
  • ErrorKind::description

travis configuration

I just had a look at the travis configuration and I wondered why you're only testing on stable and not beta and nightly.…

You could always add something like

matrix:
  allow_failures:
    - rust: nightly

travis docs for that

Fix handling of empty sections

Today all sections of the macro are optional, but the way it is handled is with '*' matchers. So instead of supporting 0 or 1 instances of any section, those sections can be repeated many times. And if that happens things go bad.

Implement ResultExt<T, ...> for Result<T, E> where E: Error

So that one can use ? instead of calling chain_err on foreign errors without first registering them with foreign_links!.

Requires specialization to still dispatch the foreign links as before (and to be possible to implement #85 as well).

Rationale: to avoid boilerplate when writing short Rust programs (the kind of programs that would be calling unwrap before error-chain). Of course foreign links or better, chain_err, is preferable on more structured programs.

Document details around recursion limits

Moving my comment from /r/rust here cause it seemed like the answers are probably useful enough to add to error-chain's docs. :}


Can you provide some more info on the consequences of increasing the program's recursion limit? What is it by default and how was the new value of 1024 chosen? Are there any performance penalties for doing this? If not, why is the default value not high enough to accommodate error-chain? Would it be possible to change error-chain's internals in a way that doesn't require recursion?

Explicit foreign_links required in v0.6 for chain_err

Hi,

seems like version 0.6 requires explicit foreign_links for chain_err to work.

On v0.5 this compiles just fine.

#[macro_use]
extern crate error_chain;
use std::fs::File;
error_chain! {
}

fn main() {
    let _r: Result<File> = File::open("abcd").chain_err(|| "some file error");
}

But on v0.6 I'm getting the below error.

#[macro_use]
extern crate error_chain;
use error_chain::ResultExt;
use std::fs::File;

error_chain! {
    // foreign_links { ::std::io::Error, Io; }
}

fn main() {
    let _r: Result<File> = File::open("abcd").chain_err(|| "some file error");
}
Running "cargo rustc -- -Zno-trans":
   Compiling experiments v0.1.0 (file:///D:/projects/rust/experiments)
error[E0277]: the trait bound `Error: std::convert::From<std::io::Error>` is not satisfied
  --> src\main.rs:11:47
   |
11 |     let _r: Result<File> = File::open("abcd").chain_err(|| "some file error");
   |                                               ^^^^^^^^^ the trait `std::convert::From<std::io::Error>` is not implemented for `Error`
   |
   = help: the following implementations were found:
   = help:   <Error as std::convert::From<ErrorKind>>
   = help:   <Error as std::convert::From<&'a str>>
   = help:   <Error as std::convert::From<std::string::String>>
   = note: required because of the requirements on the impl of `std::convert::Into<Error>` for `std::io::Error`
   = note: required because of the requirements on the impl of `error_chain::ResultExt<std::fs::File, std::io::Error, Error>` for `std::result::Result<std::fs::File, std::io::Error>`

error: aborting due to previous error

error: Could not compile `experiments`.

To learn more, run the command again with --verbose.

"cargo rustc -- -Zno-trans" completed with code 101
It took approximately 1.793 seconds

Uncommenting foreign_links { ::std::io::Error, Io; } helps, but I'm not sure whether this is intended - is implementing Error + Sync + 'static not suffiecient anymore?

Lifetime parameters

I'm trying to use error-chain in the context of a simple Lisp interpreter. One of the errors I want to handle has a lifetime parameter, but error-chain does not seem to offer a way to specify generic lifetime parameters. Is it possible?

/// LALRPOP parse error.
pub type LPParseError<'input> = ::lalrpop_util::ParseError<usize, (usize, &'input str), ()>;

// 'input should be declared somewhere around here.
error_chain!{
    errors {
        ParseError(e: LPParseError<'input>) {
            description("failed to parse")
            display("parse error: '{}'", e)
        }
    }
}
error[E0261]: use of undeclared lifetime name `'input`
 --> errors.rs:8:36
  |
8 |         ParseError(e: LPParseError<'input>) {
  |                                    ^^^^^^ undeclared lifetime

Cannot document "links" error kinds

Docstrings are allowed in the errors block, but I I've just been getting errors for those inside the links block, leaving me with missing_docs warnings. It'd be great if the macro supported documenting these variants.

quick_error!: trait bound Error not satisfied

quick_error!(
    #[derive(Debug)]
    pub enum DecodeError {
        BasicOp(val: u16) {
            description("invalid basic opcode")
            display("invalid basic opcode: {:x}", val)
        }
        SpecialOp(val: u16) {
            description("invalid special opcode")
            display("invalid special opcode: {:x}", val)
        }
    }
);

Compiler error:

src/emulator/cpu.rs:52:47: 52:48 error: the trait bound `types::DecodeError: std::error::Error` is not satisfied [E0277]
src/emulator/cpu.rs:52             Error::DecodeError(ref e) => Some(e),

description() only add a impl DecodeError and not impl Error for DecodeError.

Implement Eq on ErrorKind?

I might be holding this wrong, but I'd like to write eg

assert_eq!(*af.last_band_id().unwrap_err().kind(), ErrorKind::ArchiveEmpty);

this complains

error[E0369]: binary operation `==` cannot be applied to type `errors::ErrorKind

Is that feasible to add? Or could we add to the documentation some example of the intended way to write this?

I see I can use a destructuring match but that seems a little unnatural in a test.

error-chain doesn't work on stable 1.10!

I thought error-chain worked on stable but it doesn't seem to:

brian@ip-10-145-43-250:~/dev/error-chain⟫ cargo test
   Compiling error-chain v0.2.2 (file:///mnt/dev/error-chain)
<error_chain macros>:37:24: 37:27 error: expected expression, found keyword `pub`
<error_chain macros>:37 # [ derive ( Debug ) ] pub struct $ error_name (
                                               ^~~
error: Could not compile `error-chain`.

To learn more, run the command again with --verbose.

If I try to test further back on 1.9 the errors are even worse:

brian@ip-10-145-43-250:~/dev/error-chain⟫ cargo test
   Compiling gcc v0.3.32
   Compiling cfg-if v0.1.0
   Compiling winapi-build v0.1.1
   Compiling winapi v0.2.8
error: internal compiler error: unexpected panic
note: the compiler unexpectedly panicked. this is a bug.
note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports
thread 'rustc' panicked at 'called `Result::unwrap()` on an `Err` value: Utf8Error { valid_up_to: 0 }', ../src/libcore/result.rs:746
note: Run with `RUST_BACKTRACE=1` for a backtrace.

Build failed, waiting for other jobs to finish...
error: internal compiler error: unexpected panic
note: the compiler unexpectedly panicked. this is a bug.
note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports
thread 'rustc' panicked at 'called `Result::unwrap()` on an `Err` value: Utf8Error { valid_up_to: 0 }', ../src/libcore/result.rs:746
note: Run with `RUST_BACKTRACE=1` for a backtrace.

error: internal compiler error: unexpected panic
note: the compiler unexpectedly panicked. this is a bug.
note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports
thread 'rustc' panicked at 'called `Result::unwrap()` on an `Err` value: Utf8Error { valid_up_to: 0 }', ../src/libcore/result.rs:746
note: Run with `RUST_BACKTRACE=1` for a backtrace.

error: internal compiler error: unexpected panic
note: the compiler unexpectedly panicked. this is a bug.
note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports
thread 'rustc' panicked at 'called `Result::unwrap()` on an `Err` value: Utf8Error { valid_up_to: 0 }', ../src/libcore/result.rs:746
note: Run with `RUST_BACKTRACE=1` for a backtrace.

error: Could not compile `winapi-build`.

To learn more, run the command again with --verbose.

Support 'compound errors'

Right now error-chain expects errors to be a linear sequence of errors, but twice recently I've encountered situations where I had two errors at the same time and had to figure out something to do with them. In practice one could likely have been considered the cause and the other fallout from the original error, but this relationship wasn't reflected in their structure.

Examples:

  • During some asynchronous I/O I stashed an error away in a callback because the client library didn't allow me to pass it through as context. Later, after the I/O failed with another error, I had to decide whether to return the original error or the one that it created as fallout.
  • During cleanup on an error path, subsequent operations may themselves fail, producing multiple errors.

It would be good to have a standard way to handle these situations. I imagine a CompoundError(primary, secondary) variant that stashes the lesser error with secondary perhaps being a Vec.

Auto-derive display

If description() is defined, display() could default to it instead of "".

Inference regression

Hi,

This used to work on v0.5.

#[macro_use]
extern crate error_chain;
error_chain! { }

fn main() {
    ::std::fs::create_dir_all("path/to/some/dir")
        .chain_err(|| "Unable to create some directory").unwrap();
}

But on v0.6.1 I'm receiving this inference error:

#[macro_use]
extern crate error_chain;
use error_chain::ResultExt;
error_chain! { }

fn main() {
    ::std::fs::create_dir_all("path/to/some/dir")
        .chain_err(|| "Unable to create some directory").unwrap();
}
Running "cargo build":
   Compiling experiments v0.1.0 (file:///D:/projects/rust/experiments)
error[E0284]: type annotations required: cannot resolve `<_ as error_chain::ChainedError>::ErrorKind == _`
 --> src\main.rs:8:10
  |
8 |         .chain_err(|| "Unable to create some directory").unwrap();
  |          ^^^^^^^^^

error: aborting due to previous error

error: Could not compile `experiments`.

To learn more, run the command again with --verbose.

"cargo build" completed with code 101
It took approximately 0.638 seconds

edit: same error on v0.6.0

example seems broken

From the github README, I click on quickstart, look at the example.

I then copied the example with macro , except I added an errors.rs module, turn off default features, add the recursion limit, macro_use, bla bla, and put this inside errors.rs:

error_chain! {
    foreign_links {
        // An IO error can occur.
        Io(::std::io::Error);
    }
}

this won't compile with:

error: no rules expected the token `;`
 --> <error_chain macros>:8:42
  |
8 | types { $ error_name , $ error_kind_name ; } $ ( $ rest ) * }
  |                                          ^

error: Could not compile `goblin`.

Which is impossible for me to understand or debug.

If I remove the foreign link it compiles as expected.

Side note: I've tried to use this library about 3 times and I always end up rolling my own errors or just using something like quick_error because of issues like this.

I'm probably just dumb?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.