Deprecated: Function get_magic_quotes_gpc() is deprecated in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 99

Deprecated: The each() function is deprecated. This message will be suppressed on further calls in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 619

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1169

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176
8000 Allow `with_frame` to be called from inside a loop by emk · Pull Request #5 · RoxasShadow/rollbar-rs · GitHub
Nothing Special   »   [go: up one dir, main page]

Skip to content

Conversation

emk
Copy link
Contributor
@emk emk commented Jun 28, 2017

Thank you for providing a Rollbar client library for Rust! This is a very useful thing to have.

We use the error-trace library, which provides backtraces for where
the original error occurred. We wanted to pass these backtraces to
rollbar. But to do this, we needed to call with_frame in a loop,
and this failed as follows:

error[E0499]: cannot borrow `err_builder` as mutable more than once at a time
   --> src/errors.rs:160:21
    |
160 |                     err_builder.with_frame(fb.build());
    |                     ^^^^^^^^^^^
    |                     |
    |                     second mutable borrow occurs here
    |                     first mutable borrow occurs here
...
166 |     }
    |     - first borrow ends here

error[E0499]: cannot borrow `err_builder` as mutable more than once at a time
   --> src/errors.rs:164:9
    |
160 |                     err_builder.with_frame(fb.build());
    |                     ----------- first mutable borrow occurs here
...
164 |         err_builder.send();
    |         ^^^^^^^^^^^ second mutable borrow occurs here
165 |         Ok(())
166 |     }
    |     - first borrow ends here

The problem occurs because of a subtle lifetime issue in the function
declaration:

impl<'a> ReportErrorBuilder<'a> {
    // ...
    pub fn with_frame(&'a mut self, frame_builder: FrameBuilder) -> &'a mut Self {
    // ...
}

Here, Self refers to the type ReportErrorBuilder<'a>, which contains
the lifetime 'a. But the the with_frame function uses a mutable
reference &'a mut self, which also includes 'a. This says that the
reference to ReportErrorBuilder has the same lifetime as the
ReportErrorBuilder itself, which makes it impossible to use the
function anywhere except in a "fluent" call chain:

let payload = client.build_report()
    .from_error_message(&e)
    .with_level(Level::WARNING)
    .with_frame(FrameBuilder::new()
                .with_column_number(42)
                .build())
    .with_frame(FrameBuilder::new()
                .with_column_number(24)
                .build())
    .with_title("w")
    .to_string();

But if we change the signature to:

pub fn with_frame(&mut self, frame_builder: FrameBuilder) -> &mut Self {

...then Rust will automatically generate a new lifetime (call it 'b)
for the &mut reference. This will make everything work nicely. In
this case, Rust's defaults do exactly what you want.

You may also want to apply a similar fix to with_backtrace, but I
haven't looked at that yet.

We use the `error-trace` library, which provides backtraces for where
the original error occurred.  We wanted to pass these backtraces to
`rollbar`.  But to do this, we needed to call `with_frame` in a loop,
and this failed as follows:

    error[E0499]: cannot borrow `err_builder` as mutable more than once at a time
       --> src/errors.rs:160:21
        |
    160 |                     err_builder.with_frame(fb.build());
        |                     ^^^^^^^^^^^
        |                     |
        |                     second mutable borrow occurs here
        |                     first mutable borrow occurs here
    ...
    166 |     }
        |     - first borrow ends here

    error[E0499]: cannot borrow `err_builder` as mutable more than once at a time
       --> src/errors.rs:164:9
        |
    160 |                     err_builder.with_frame(fb.build());
        |                     ----------- first mutable borrow occurs here
    ...
    164 |         err_builder.send();
        |         ^^^^^^^^^^^ second mutable borrow occurs here
    165 |         Ok(())
    166 |     }
        |     - first borrow ends here

The problem occurs because of a subtle lifetime issue in the function
declaration:

    impl<'a> ReportErrorBuilder<'a> {
        // ...
        pub fn with_frame(&'a mut self, frame_builder: FrameBuilder) -> &'a mut Self {
        // ...
    }

Here, `Self` refers to the type `ReportErrorBuilder<'a>`, which contains
the lifetime `'a`.  But the the `with_frame` function uses a mutable
reference `&'a mut self`, which also includes `'a`. This says that the
_reference_ to `ReportErrorBuilder` has the same lifetime as the
`ReportErrorBuilder` itself, which makes it impossible to use the
function anywhere except in a "fluent" call chain:

    let payload = client.build_report()
        .from_error_message(&e)
        .with_level(Level::WARNING)
        .with_frame(FrameBuilder::new()
                    .with_column_number(42)
                    .build())
        .with_frame(FrameBuilder::new()
                    .with_column_number(24)
                    .build())
        .with_title("w")
        .to_string();

But if we change the signature to:

    pub fn with_frame(&mut self, frame_builder: FrameBuilder) -> &mut Self {

...then Rust will automatically generate a new lifetime (call it `'b`)
for the `&mut` reference.  This will make everything work nicely.  In
this case, Rust's defaults do exactly what you want.

You may also want to apply a similar fix to `with_backtrace`, but I
haven't looked at that yet.
@RoxasShadow
Copy link
Owner

@emk I'm really sorry for the delay, I noticed this PR only today. Somehow I didn't notice any email notification from GitHub about it.

Anyway, the point you highlighted looks reasonable. I'm going to merge these changes, bump the crate dependencies and push a new version to crates.io.

Thank you and again sorry for the delay.

@RoxasShadow RoxasShadow merged commit 07726a2 into RoxasShadow:master Jul 12, 2017
RoxasShadow added a commit that referenced this pull request Jul 12, 2017
@emk
Copy link
Contributor Author
emk commented Jul 12, 2017

Thank you for merging this patch, and for providing a very handy library!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

0