{"record":{"id":"c35885edf563b44e","repo":"t8y2/dbx","slug":"server-error","errorCode":null,"errorMessage":"Server error","messagePattern":"Server error","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"crates/dbx-web/src/main.rs","lineNumber":1134,"sourceCode":"    if public_base_path != \"/\" {\n        tracing::info!(\"Serving DBX Web under context path {}\", public_base_path);\n    }\n    if password_disabled {\n        tracing::info!(\"Password protection is disabled\");\n    } else if std::env::var(\"DBX_PASSWORD\").is_ok() {\n        tracing::info!(\"Password protection is enabled\");\n    }\n\n    let listener = tokio::net::TcpListener::bind(addr).await.expect(\"Failed to bind address\");\n    let shutdown_state = web_state.app.clone();\n    axum::serve(listener, app)\n        .with_graceful_shutdown(async {\n            if let Err(error) = tokio::signal::ctrl_c().await {\n                tracing::warn!(\"Failed to listen for shutdown signal: {error}\");\n            }\n        })\n        .await\n        .expect(\"Server error\");\n    shutdown_state.shutdown(std::time::Duration::from_secs(3)).await;\n}\n\n#[cfg(test)]\nmod tests {\n    use super::{\n        mount_public_base_path, normalize_public_base_path, web_agent_dir_from_env, web_body_limit_bytes_from_value,\n        web_compression_predicate, XLSX_CONTENT_TYPE,\n    };\n    use crate::routes::table_import;\n    use axum::body::Body;\n    use axum::extract::{DefaultBodyLimit, Multipart};\n    use axum::http::header::CONTENT_TYPE;\n    use axum::http::{Response, StatusCode};\n    use axum::routing::{get, post};\n    use axum::Router;\n    use tower_http::compression::predicate::Predicate;\n","sourceCodeStart":1116,"sourceCodeEnd":1152,"githubUrl":"https://github.com/t8y2/dbx/blob/c0390bff16418b651f4728520d99adf8ce48829a/crates/dbx-web/src/main.rs#L1116-L1152","documentation":"dbx-web runs axum::serve(listener, app).with_graceful_shutdown(ctrl_c) and expects the server future to complete without error. The expect fires when the serving loop terminates with an Err, i.e., a fatal server-side failure after startup.","triggerScenarios":"axum::serve returns Err when the accept loop fails fatally — e.g., the listener socket becomes invalid, an OS-level accept error occurs repeatedly, or the runtime shuts down unexpectedly before ctrl_c.","commonSituations":"The listening socket being closed externally (container network teardown, firewall/security software); file-descriptor exhaustion (EMFILE) causing accept failures; abrupt process environment changes like the network interface disappearing.","solutions":["Check system logs / OS errors around the crash time (fd limits: ulimit -n, dmesg, container events).","Raise the file descriptor limit and ensure the host does not forcibly close the socket.","Run dbx-web under a supervisor (systemd/docker restart policy) so a fatal serve error triggers a restart.","Replace expect() with error handling that logs the io::Error and performs graceful shutdown_state.shutdown() before exiting."],"exampleFix":"// before\n.await\n.expect(\"Server error\");\n// after\n.await\n    .unwrap_or_else(|e| eprintln!(\"Server error: {e}\"));\nshutdown_state.shutdown(std::time::Duration::from_secs(3)).await;","handlingStrategy":"try-catch","validationCode":"// pre-flight: ensure fd headroom for the accept loop\nlet fds_free = (unsafe { libc::getrlimit(libc::RLIMIT_NOFILE) }).rlim_cur > 1024;","typeGuard":null,"tryCatchPattern":"if let Err(e) = axum::serve(listener, app)\n    .with_graceful_shutdown(async { let _ = tokio::signal::ctrl_c().await; })\n    .await\n{\n    tracing::error!(\"Server error: {e}\");\n}\nshutdown_state.shutdown(std::time::Duration::from_secs(3)).await;","preventionTips":["Run the server under systemd or a container restart policy.","Raise RLIMIT_NOFILE for high-connection workloads.","Monitor accept errors and host network events.","Always run shutdown_state.shutdown on any exit path."],"tags":["axum","rust","server","network"],"backgroundTag":"server-runtime-failure","analyzedSha":"c0390bff16418b651f4728520d99adf8ce48829a","analyzedAt":"2026-09-05T23:05:10.900Z","contentChangedAt":"2026-09-05T23:05:10.900Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}