0

I am fairly new to rust and trying to connect to gmail api to read emails. I am using yup_oauth2 to authenticate and then google_gmail1 to read emails. here is my code

use yup_oauth2::{InstalledFlowAuthenticator, InstalledFlowReturnMethod};
use tokio::io::{stdout, AsyncWriteExt as _};

extern crate google_gmail1 as gmail1;
use gmail1::api::Message;
use gmail1::{Result, Error};
use std::fs;
use gmail1::{Gmail, oauth2, hyper , hyper_rustls , chrono, FieldMask};

#[tokio::main]

async fn main() {
    // Read application secret from a file. Sometimes it's easier to compile it directly into
    // the binary. The clientsecret file contains JSON like `{"installed":{"client_id": ... }}`
    let secret = yup_oauth2::read_application_secret("D:\\email-summarizer\\src\\client_secret.json")
        .await
        .expect("D:\\email-summarizer\\src\\client_secret.json");

    // Create an authenticator that uses an InstalledFlow to authenticate. The
    // authentication tokens are persisted to a file named tokencache.json. The
    // authenticator takes care of caching tokens to disk and refreshing tokens once
    // they've expired.
    let  auth = InstalledFlowAuthenticator::builder(secret, InstalledFlowReturnMethod::HTTPRedirect)
    .persist_tokens_to_disk("tokencache.json")
    .build()
    .await
    .unwrap();

    let scopes = &["https://www.googleapis.com/auth/drive.file"];

    let mut hub = Gmail::new(
        hyper::Client::builder().build(
            hyper_rustls::HttpsConnectorBuilder::new().with_native_roots().https_or_http().enable_http1().enable_http2().build()),
             auth);
    let mut req = Message::default();
    let result = hub.users().messages_import(req, "userId")
    .process_for_calendar(true)
    .never_mark_spam(true)
    .internal_date_source("Lorem")
    .deleted(false)
    .upload_resumable(fs::File::open("D:\\email-summarizer\\src\\file.ext").unwrap(), "application/octet-stream".parse().unwrap()).await;    

    match result {
    Err(e) => match e {
        // The Error enum provides details about what exactly happened.
        // You can also just use its `Debug`, `Display` or `Error` traits
         Error::HttpError(_)
        |Error::Io(_)
        |Error::MissingAPIKey
        |Error::MissingToken(_)
        |Error::Cancelled
        |Error::UploadSizeLimitExceeded(_, _)
        |Error::Failure(_)
        |Error::BadRequest(_)
        |Error::FieldClash(_)
        |Error::JsonDecodeError(_, _) => println!("{}", e),
    },
    Ok(res) => println!("Success: {:?}", res),
}
    
}

but when i am running it is giving the following error.


thread 'main' panicked at 'attempt to subtract with overflow', C:\Users\DC\.cargo\registry\src\github.com-1ecc6299db9ec823\google-apis-common-5.0.2\src\lib.rs:691:27

here is the backtrace


  0: std::panicking::begin_panic_handler
             at /rustc/fc594f15669680fa70d255faec3ca3fb507c3405/library\std\src\panicking.rs:575      
   1: core::panicking::panic_fmt
             at /rustc/fc594f15669680fa70d255faec3ca3fb507c3405/library\core\src\panicking.rs:64      
   2: core::panicking::panic
             at /rustc/fc594f15669680fa70d255faec3ca3fb507c3405/library\core\src\panicking.rs:111     
   3: google_apis_common::impl$14::upload::async_fn$0<alloc::boxed::Box<dyn$<google_apis_common::auth::GetToken>,alloc::alloc::Global>,hyper_rustls::connector::HttpsConnector<hyper::client::connect::http::HttpConnector<hyper::client::connect::dns::GaiResolver>
             at C:\Users\DC\.cargo\registry\src\github.com-1ecc6299db9ec823\google-apis-common-5.0.2\src\lib.rs:691
   4: google_gmail1::api::impl$110::doit::async_fn$0<hyper_rustls::connector::HttpsConnector<hyper::client::connect::http::HttpConnector<hyper::client::connect::dns::GaiResolver> >,std::fs::File>
             at C:\Users\DC\.cargo\registry\src\github.com-1ecc6299db9ec823\google-gmail1-5.0.2+20230116\src\api.rs:9036
   5: google_gmail1::api::impl$110::upload_resumable::async_fn$0<hyper_rustls::connector::HttpsConnector<hyper::client::connect::http::HttpConnector<hyper::client::connect::dns::GaiResolver> >,std::fs::File>
             at C:\Users\DC\.cargo\registry\src\github.com-1ecc6299db9ec823\google-gmail1-5.0.2+20230116\src\api.rs:9090
   6: email_summarizer::main::async_block$0
             at .\src\main.rs:41
   7: tokio::runtime::park::impl$4::block_on::closure$0<enum2$<email_summarizer::main::async_block_env$0> >
             at C:\Users\DC\.cargo\registry\src\github.com-1ecc6299db9ec823\tokio-1.27.0\src\runtime\park.rs:283
   8: tokio::runtime::coop::with_budget
             at C:\Users\DC\.cargo\registry\src\github.com-1ecc6299db9ec823\tokio-1.27.0\src\runtime\coop.rs:107
   9: tokio::runtime::coop::budget
             at C:\Users\DC\.cargo\registry\src\github.com-1ecc6299db9ec823\tokio-1.27.0\src\runtime\coop.rs:73
  10: tokio::runtime::park::CachedParkThread::block_on<enum2$<email_summarizer::main::async_block_env$0> >
             at C:\Users\DC\.cargo\registry\src\github.com-1ecc6299db9ec823\tokio-1.27.0\src\runtime\park.rs:283
  11: tokio::runtime::context::BlockingRegionGuard::block_on<enum2$<email_summarizer::main::async_block_env$0> >
             at C:\Users\DC\.cargo\registry\src\github.com-1ecc6299db9ec823\tokio-1.27.0\src\runtime\context.rs:315
  12: tokio::runtime::scheduler::multi_thread::MultiThread::block_on<enum2$<email_summarizer::main::async_block_env$0> >
             at C:\Users\DC\.cargo\registry\src\github.com-1ecc6299db9ec823\tokio-1.27.0\src\runtime\scheduler\multi_thread\mod.rs:66
  13: tokio::runtime::runtime::Runtime::block_on<enum2$<email_summarizer::main::async_block_env$0> >  
             at C:\Users\DC\.cargo\registry\src\github.com-1ecc6299db9ec823\tokio-1.27.0\src\runtime\runtime.rs:304
  14: email_summarizer::main
             at .\src\main.rs:43
  15: core::ops::function::FnOnce::call_once<void (*)(),tuple$<> >
             at /rustc/fc594f15669680fa70d255faec3ca3fb507c3405\library\core\src\ops\function.rs:507  
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose back

trace.

I know that the error is causing because in the following section -1 is getting subtracted from 0.but i dont know what causing it. I have tried changing this section in google-apis-common-5.0.2\src\lib.rs:691:27

let mut section_reader = self.reader.take(request_size);
            let mut req_bytes = vec![];
            section_reader.read_to_end(&mut req_bytes).unwrap();
            let range_header = ContentRange {
                range: Some(Chunk {
                    first: start,
                    last: start + request_size - 1,
                }),
                total_length: self.content_length,
            };
            if self.delegate.cancel_chunk_upload(&range_header) {
                return None;

to


let mut section_reader = self.reader.take(request_size);
            let mut req_bytes = vec![];
            section_reader.read_to_end(&mut req_bytes).unwrap();
            let range_header = ContentRange {
                range: Some(Chunk {
                    first: start,
                    last: start + request_size - idx.wrapping_sub(1),
                }),
                total_length: self.content_length,
            };
            if self.delegate.cancel_chunk_upload(&range_header) {
                return None;
glitch_123
  • 139
  • 12
  • Is line 43 `match result {`? That doesn't look right... – Peter Hall Apr 06 '23 at 19:57
  • @PeterHall yes, it is. should it be something else? – glitch_123 Apr 06 '23 at 20:05
  • Is `D:\email-summarizer\src\file.ext` missing, inaccessible, or empty? – Solomon Ucko Apr 06 '23 at 20:05
  • @SolomonUcko yes file.ext is empty. I am very much new to it. should there be something in file.ext? – glitch_123 Apr 06 '23 at 20:06
  • Yeah, I think it should contain the message to send. `ResumableUploadHelper::upload` apparently crashes if given an empty file. If that's actually your goal, you can submit a bug report here: https://github.com/Byron/google-apis-rs/issues. – Solomon Ucko Apr 06 '23 at 20:12
  • thank you! adding something to file.ext solve the error. But since I only want to read messages should i use messages_get method? – glitch_123 Apr 06 '23 at 20:24
  • @glitch_123 Ok coo, makes sense. Based on [the documentation](https://docs.rs/google-gmail1/latest/google_gmail1/api/struct.UserMethods.html), I think you should just use [`messages_list`](https://docs.rs/google-gmail1/latest/google_gmail1/api/struct.UserMethods.html#method.messages_list) and [`messages_get`](https://docs.rs/google-gmail1/latest/google_gmail1/api/struct.UserMethods.html#method.messages_get), not [`messages_import`](https://docs.rs/google-gmail1/latest/google_gmail1/api/struct.UserMethods.html#method.messages_import). – Solomon Ucko Apr 06 '23 at 20:29

1 Answers1

0

request_size seems unsigned, as the u32 type e.g. (and I think has got the zero 0 value). When you subtracts -1 on, by default Rust panics (out of the "release" mode).

https://doc.rust-lang.org/std/intrinsics/fn.sub_with_overflow.html

You may cast request_size as a signed int, as the i32 type e.g., if the range.last field accepts it.