Rust初心者なので変なところで躓いてしまった。
要約
nickel_diesel crateをつかおうとして凡ミスに気づかず謎のクラッシュでハマったので気をつけようというお話。
RouterのHandler内でDatabase接続を使用するときには、Database接続を先にNickelに utilize
しておこう。
そうでないと crash する。
$ cargo run
Finished dev [unoptimized + debuginfo] target(s) in 0.14s
Running `target/debug/myblog-rs`
Listening on http://127.0.0.1:8019
Ctrl-C to shutdown server
thread '<unnamed>' panicked at 'called `Option::unwrap()` on a `None` value', libcore/option.rs:335:21
note: Run with `RUST_BACKTRACE=1` for a backtrace.
実装
extern crate
とか use
とかは省いて、概ねこんな感じ。
このコードの server.utilize(db_pool);
と server.utilize(router());
の行を逆に書いてしまうと、Databaseの接続が取得できずに (None
が取れてしまって) ランタイムでクラッシュする。
具体的には、当該URLに対してHTTPリクエストを投げたときにクラッシュする。Backtrace見ると、index
関数の req.db_conn()
している行で落ちる。
fn main() {
let mut server: = Nickel::new();
let mysql_url = "mysql://root:password@127.0.0.1:13306/blog";
let connections: u32 = 5;
let db_pool: DieselMiddleware<MysqlConnection> =
DieselMiddleware::new(mysql_url, connections, Box::new(NopErrorHandler)).unwrap();
server.utilize(db_pool);
server.utilize(router());
server.listen("127.0.0.1:8019").unwrap();
}
fn router() -> Router {
let mut router: = Nickel::router();
router.get("/", index);
router
}
fn index<'mw>(req: &mut Request, res: Response<'mw>) -> MiddlewareResult<'mw> {
let conn: PooledConnection<ConnectionManager<MysqlConnection>> = req.db_conn();
let result = conn.execute("SELECT 1").unwrap();
res.send(format!("{}", result))
}