I’m trying to update my app to v1.0.0 from using v0.3.12 and I want to use the sync API for now (just because It’s easier and is what I’ve already built for). I’m trying to use Client with_uri_str so that I can just pass it a mongo connection string and be on my way, but I’m getting this panic when I do so:
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Error { kind: ServerSelectionError { message: "Server selection timeout: No available servers. Topology: { Type: Unknown, Servers: [ { Address: <server_address>:27017, Type: Unknown, Error: tls handshake eof }, ] }" } }', src/lib.rs:715:18
My server apparently requires tls, but It’s unclear to me how to enable it with sync API. I shouldn’t need any certs or anything since my connection string works fine in the mongo cli. How does one go about connecting using TLS this way? Can I somehow pass client options while using a URL? Also wondering about parse, but that’s async, so I can’t use it AFAIK. Any help is appreciated!
When you provide a URI to configure the Client, tls is automatically set to true. My theory is that your server isn’t configured with TLS support, which would explain why your TLS handshake is failing. To fix this you can add the param tls=false to your URI, although it would probably be better to enable TLS on your server for security instead.
Okay, so I did some experiments with the mongo CLI tool, and found that I had to have ssl=true or tls=true in order to connect. Otherwise, it’d give me an error that looked something like this:
MongoDB shell version v4.2.6
connecting to: mongodb://<ip_address>:27017/<db_name>?compressors=disabled&gssapiServiceName=mongodb&tls=false
2020-08-16T16:06:40.982+0000 I NETWORK [js] DBClientConnection failed to receive message from <ip_address>:27017 - HostUnreachable: Connection closed by peer
2020-08-16T16:06:40.983+0000 E QUERY [js] Error: network error while attempting to run command 'isMaster' on host '<ip_address>:27017' :
connect@src/mongo/shell/mongo.js:341:17
@(connect):2:6
2020-08-16T16:06:40.986+0000 F - [main] exception: connect failed
2020-08-16T16:06:40.986+0000 E - [main] exiting with code 1
Not sure what’s wrong now. I should just be able to connect with that URL, just like I can with the CLI, right?
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Error { kind: ServerSelectionError { message: "Server selection timeout: No available servers. Topology: { Type: Unknown, Servers: [ { Address: <ip_address>:27017, Type: Unknown, Error: tls handshake eof }, ] }" } }', src/lib.rs:716:18
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
When I do this:
let coll = mongo_client
.database("<db>")
.collection(&collection);
let mut namespace_table = Vec::new(); // The vec of namespace information we're gonna send back.
// Find the document and receive a cursor
dbg!(&coll);
let cursor = coll.find(None, None).unwrap();
And I believe it’s panicing on that unwrap.
The source code can be found here, if you want to take a look.
What I actually did that made things work is this: export SSL_CERT_FILE=$(python3 -c "import certifi; print(certifi.where())")
and then all my Mongo stuff started working, mongo and mongosh and PHP and Python.
I dunno, something is flakey with the certs, not sure what the problem is, but I’ve got it working, and it wasn’t working before
@wilnil It’s worth noting that the mongodb crate has been rewritten since 0.3.12. It would be worth looking at the 1.1 release and maybe porting your code. I don’t think it would take much more effort than a few search&replaces, and you’ll be getting a fully supported up-to-date driver.
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Error { kind: ServerSelectionError { message: "Server selection timeout: No available servers. Topology: { Type: Unknown, Servers: [ { Address: <ip_address>:27017, Type: Unknown, Error: tls handshake eof }, ] }" } }', src/lib.rs:716:18
stack backtrace:
0: backtrace::backtrace::libunwind::trace
at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.46/src/backtrace/libunwind.rs:86
1: backtrace::backtrace::trace_unsynchronized
at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.46/src/backtrace/mod.rs:66
2: std::sys_common::backtrace::_print_fmt
at src/libstd/sys_common/backtrace.rs:78
3: <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt
at src/libstd/sys_common/backtrace.rs:59
4: core::fmt::write
at src/libcore/fmt/mod.rs:1076
5: std::io::Write::write_fmt
at src/libstd/io/mod.rs:1537
6: std::sys_common::backtrace::_print
at src/libstd/sys_common/backtrace.rs:62
7: std::sys_common::backtrace::print
at src/libstd/sys_common/backtrace.rs:49
8: std::panicking::default_hook::{{closure}}
at src/libstd/panicking.rs:198
9: std::panicking::default_hook
at src/libstd/panicking.rs:218
10: std::panicking::rust_panic_with_hook
at src/libstd/panicking.rs:486
11: rust_begin_unwind
at src/libstd/panicking.rs:388
12: core::panicking::panic_fmt
at src/libcore/panicking.rs:101
13: core::option::expect_none_failed
at src/libcore/option.rs:1272
14: core::result::Result<T,E>::unwrap
at /rustc/d3fb005a39e62501b8b0b356166e515ae24e2e54/src/libcore/result.rs:1005
15: shelflife::get_db
at src/lib.rs:716
16: shelflife::view_db
at src/lib.rs:757
17: shelflife::main
at src/bin/main.rs:233
18: std::rt::lang_start::{{closure}}
at /rustc/d3fb005a39e62501b8b0b356166e515ae24e2e54/src/libstd/rt.rs:67
19: std::rt::lang_start_internal::{{closure}}
at src/libstd/rt.rs:52
20: std::panicking::try::do_call
at src/libstd/panicking.rs:297
21: std::panicking::try
at src/libstd/panicking.rs:274
22: std::panic::catch_unwind
at src/libstd/panic.rs:394
23: std::rt::lang_start_internal
at src/libstd/rt.rs:51
24: std::rt::lang_start
at /rustc/d3fb005a39e62501b8b0b356166e515ae24e2e54/src/libstd/rt.rs:67
25: main
26: __libc_start_main
27: _start
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
And as to your second point, I thought it would work the way it is, but at this point, yeah. I’ll have to go through it and port my logic.
It’s this block here that it’s failing on. Is there a “new” way to do that?
let coll = mongo_client
.database("shelflife")
.collection(&collection);
let mut namespace_table = Vec::new(); // The vec of namespace information we're gonna send back.
// Find the document and receive a cursor
dbg!(&coll);
let cursor = coll.find(None, None).unwrap();
I see that there is a sync api example. Do you think it’ll work if I copy it? I’ll try it out after work today and report back. Thanks for the help!