rust-lang-deprecated / error-chain Goto Github PK
View Code? Open in Web Editor NEWError boilerplate for Rust
License: Apache License 2.0
Error boilerplate for Rust
License: Apache License 2.0
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?
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
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
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.
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.
Most of the 'sections' of the macro can be empty, but it would be better if they could be excluded altogether. I'm just not good enough with macros to implement it.
It can just delegate to the foreign error. cc @cramertj.
I'd say it's not worth maintaining backwards compatibility, since there aren't a whole lot of users, but it will be a 'major' version bump.
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
There are many tests that have types { Error, ErrorKind, Result }
instead of types { Error, ErrorKind, ResultExt, Result }
and thus are actually defining the ResultExt
trait's name to be Result
.
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.
Here is a minimal example, the real example is a bit larger.
Shouldn't this work?
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()
See errors.rs for an example.
As far as I can see it is not possible to add documentation to the 3 fields of BridgeError.
It would be nice if that could be made possible in some way.
Today the sections have to be defined in a strict order. This is mostly just because it's easier to implement. It would be better if sections could appear in any order.
cc #38
It is currently impossible to call chain_err
on Result
s that have a boxed std::error::Error
trait-object as Err
variant. Since the cause of an error-chain error is stored as a boxed trait-object anyway, it would be nice to have this functionality.
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.
Subj.
The problem described here: rust-lang-nursery/rustup.rs#591. Guess issue related to this crate since backtrace-rs is explicit thing to deal with it.
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
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?
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?
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 Result
s. 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?
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?
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.
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.
If description()
is defined, display()
could default to it instead of ""
.
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
.
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.
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();
}
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:
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
.
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:
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.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.
Current file is outdated, upstream has new features and a doc.
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.
Would it be possible to make backtrace support optional?
It brings in dependency on dbghelp
and consecutively does not work on WinXP/2003.
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?
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...
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?
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.
The problem: rust-lang/rust#24827. That's why the attributes have to be put at the end of the links
and foreign_links
declarations.
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?
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.
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?
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.
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;
}
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.
ChainErr
trait. A similar named trait could lead to some confusion.Alternatively, the compound error could just be a type-alias for a specific variant of a generic struct. I.e.
pub enum $error_kind_name { /* ... */ }
type $error_name = ErrorChain<$error_kind_name>;
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;
}
I'm wondering if this is suitable for representing errors in a potential out-of-memory condition (i.e. malloc failure)?
Yet Cargo.toml
contains licence field:
license = "MIT/Apache-2.0"
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
$ 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.
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.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.