the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `std::ops::Try`)

Viewed 2329

I am doing my assignment that's include make connection with the database in Rust. I am using the latest version of mysql crate: mysql ="18.2.0".My Database connection is successful as I print the pool variable. I write my own code for table student but I get the error. Then i paste the code of documentation, I recieve the following error with'?' operator:

I am connecting the database in rust for the first time. Any help is appreciated.

warning: unused import: `std::io`
 --> src/main.rs:2:5
  |
2 | use std::io;
  |     ^^^^^^^
  |
  = note: `#[warn(unused_imports)]` on by default

error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `std::ops::Try`)
  --> src/main.rs:17:12
   |
14 | / fn insert(){
15 | |
16 | |
17 | | let pool = Pool::new("mysql://root:root@localhost:3306/Rust_testing")?;
   | |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot use the `?` operator in a function that returns `()`
...  |
58 | |
59 | | }
   | |_- this function should return `Result` or `Option` to accept `?`
   |
   = help: the trait `std::ops::Try` is not implemented for `()`
   = note: required by `std::ops::Try::from_error`

error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `std::ops::Try`)
  --> src/main.rs:19:16
   |
14 | / fn insert(){
15 | |
16 | |
17 | | let pool = Pool::new("mysql://root:root@localhost:3306/Rust_testing")?;
18 | |
19 | | let mut conn = pool.get_conn()?;
   | |                ^^^^^^^^^^^^^^^^ cannot use the `?` operator in a function that returns `()`
...  |
58 | |
59 | | }
   | |_- this function should return `Result` or `Option` to accept `?`
   |
   = help: the trait `std::ops::Try` is not implemented for `()`
   = note: required by `std::ops::Try::from_error`

error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `std::ops::Try`)
  --> src/main.rs:22:1
   |
14 |  / fn insert(){
15 |  |
16 |  |
17 |  | let pool = Pool::new("mysql://root:root@localhost:3306/Rust_testing")?;
...   |
22 | /| conn.query_drop(
23 | ||     r"CREATE TEMPORARY TABLE payment (
24 | ||         customer_id int not null,
25 | ||         amount int not null,
26 | ||         account_name text
27 | ||     )")?;
   | ||________^ cannot use the `?` operator in a function that returns `()`
...   |
58 |  |
59 |  | }
   |  |_- this function should return `Result` or `Option` to accept `?`
   |
   = help: the trait `std::ops::Try` is not implemented for `()`
   = note: required by `std::ops::Try::from_error`

error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `std::ops::Try`)
  --> src/main.rs:38:1
   |
14 |  / fn insert(){
15 |  |
16 |  |
17 |  | let pool = Pool::new("mysql://root:root@localhost:3306/Rust_testing")?;
...   |
38 | /| conn.exec_batch(
39 | ||     r"INSERT INTO payment (customer_id, amount, account_name)
40 | ||       VALUES (:customer_id, :amount, :account_name)",
41 | ||     payments.iter().map(|p| params! {
...  ||
45 | ||     })
46 | || )?;
   | ||__^ cannot use the `?` operator in a function that returns `()`
...   |
58 |  |
59 |  | }
   |  |_- this function should return `Result` or `Option` to accept `?`
   |
   = help: the trait `std::ops::Try` is not implemented for `()`
   = note: required by `std::ops::Try::from_error`

error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `std::ops::Try`)
  --> src/main.rs:49:25
   |
14 |  / fn insert(){
15 |  |
16 |  |
17 |  | let pool = Pool::new("mysql://root:root@localhost:3306/Rust_testing")?;
...   |
49 |  | let selected_payments = conn
   |  |_________________________^
50 | ||     .query_map(
51 | ||         "SELECT customer_id, amount, account_name from payment",
52 | ||         |(customer_id, amount, account_name)| {
53 | ||             Payment { customer_id, amount, account_name }
54 | ||         },
55 | ||     )?;
   | ||______^ cannot use the `?` operator in a function that returns `()`
...   |
58 |  |
59 |  | }
   |  |_- this function should return `Result` or `Option` to accept `?`
   |
   = help: the trait `std::ops::Try` is not implemented for `()`
   = note: required by `std::ops::Try::from_error`

error: aborting due to 5 previous errors; 1 warning emitted

For more information about this error, try `rustc --explain E0277`.
error: could not compile `class-09`.

Here is the code, i copy from documentation to test:

 use std::io;
    
    use mysql::prelude::*;
    use mysql::*;
    
    
    #[derive(Debug, PartialEq, Eq)]
    struct Payment {
        customer_id: i32,
        amount: i32,
        account_name: Option<String>,
    }

fn insert(){
    let pool = Pool::new("mysql://root:root@localhost:3306/Rust_testing")?;

let mut conn = pool.get_conn()?;

// Let's create a table for payments.
conn.query_drop(
    r"CREATE TEMPORARY TABLE payment (
        customer_id int not null,
        amount int not null,
        account_name text
    )")?;

let payments = vec![
    Payment { customer_id: 1, amount: 2, account_name: None },
    Payment { customer_id: 3, amount: 4, account_name: Some("foo".into()) },
    Payment { customer_id: 5, amount: 6, account_name: None },
    Payment { customer_id: 7, amount: 8, account_name: None },
    Payment { customer_id: 9, amount: 10, account_name: Some("bar".into()) },
];

// Now let's insert payments to the database
conn.exec_batch(
    r"INSERT INTO payment (customer_id, amount, account_name)
      VALUES (:customer_id, :amount, :account_name)",
    payments.iter().map(|p| params! {
        "customer_id" => p.customer_id,
        "amount" => p.amount,
        "account_name" => &p.account_name,
    })
)?;

// Let's select payments from database. Type inference should do the trick here.
let selected_payments = conn
    .query_map(
        "SELECT customer_id, amount, account_name from payment",
        |(customer_id, amount, account_name)| {
            Payment { customer_id, amount, account_name }
        },
    )?;

println!("Yay!");

}

fn main(){
    insert();
}

and when i write my code without the ? operator, I got the following error:

warning: unused import: `std::io`
 --> src/main.rs:2:5
  |
2 | use std::io;
  |     ^^^^^^^
  |
  = note: `#[warn(unused_imports)]` on by default

error[E0599]: no method named `query_drop` found for enum `std::result::Result<mysql::conn::pool::PooledConn, mysql::error::Error>` in the current scope
  --> src/main.rs:32:6
   |
32 | conn.query_drop(
   |      ^^^^^^^^^^ method not found in `std::result::Result<mysql::conn::pool::PooledConn, mysql::error::Error>`

error[E0599]: no method named `exec_batch` found for enum `std::result::Result<mysql::conn::pool::PooledConn, mysql::error::Error>` in the current scope
  --> src/main.rs:48:6
   |
48 | conn.exec_batch(
   |      ^^^^^^^^^^ method not found in `std::result::Result<mysql::conn::pool::PooledConn, mysql::error::Error>`

error[E0599]: no method named `query_map` found for enum `std::result::Result<mysql::conn::pool::PooledConn, mysql::error::Error>` in the current scope
  --> src/main.rs:60:6
   |
60 |     .query_map(
   |      ^^^^^^^^^ method not found in `std::result::Result<mysql::conn::pool::PooledConn, mysql::error::Error>`

warning: unused import: `mysql::prelude`
 --> src/main.rs:4:5
  |
4 | use mysql::prelude::*;
  |     ^^^^^^^^^^^^^^

error: aborting due to 3 previous errors; 2 warnings emitted

For more information about this error, try `rustc --explain E0599`.
error: could not compile `class-09`.
1 Answers

As the compiler is telling you: you are missing a return type in your function. The ? operator will return (propagate) the error if any, but for that to work you need to have a return type that can be constructed with the error type.

For prototyping, you can just call unwrap. But this approach should be carefully considered when writing production code, as it will just crash the program when the function returns an error.

find more here

Related