debug: Add panic hook and numbered steps to diagnose startup issue
This commit is contained in:
parent
b3d5304bf6
commit
c82160ca11
1 changed files with 31 additions and 28 deletions
|
|
@ -17,23 +17,35 @@ use tower_http::{
|
||||||
};
|
};
|
||||||
use config::Config;
|
use config::Config;
|
||||||
|
|
||||||
|
// Set up panic hook to catch panics before main
|
||||||
|
fn setup_panic_hook() {
|
||||||
|
std::panic::set_hook(Box::new(|panic_info| {
|
||||||
|
let msg = panic_info.to_string();
|
||||||
|
println!("[PANIC] {}", msg);
|
||||||
|
let location = panic_info.location().unwrap_or_else(|| std::panic::Location::caller());
|
||||||
|
println!("[PANIC] Location: {}:{}:{}", location.file(), location.line(), location.column());
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> anyhow::Result<()> {
|
async fn main() -> anyhow::Result<()> {
|
||||||
// Use println! which is more reliable in Docker
|
// Install panic hook FIRST
|
||||||
println!("=== NORMOGEN BACKEND STARTING ===");
|
setup_panic_hook();
|
||||||
println!("[STARTUP] Loading environment variables...");
|
|
||||||
|
// IMMEDIATE output - this MUST show up
|
||||||
|
println!("=== NORMOGEN STARTING ===");
|
||||||
|
println!("[1/7] Loading environment variables...");
|
||||||
|
|
||||||
match dotenv::dotenv() {
|
match dotenv::dotenv() {
|
||||||
Ok(path) => {
|
Ok(path) => {
|
||||||
println!("[STARTUP] Loaded .env from: {:?}", path);
|
println!("[1/7] Loaded .env from: {:?}", path);
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(_) => {
|
||||||
println!("[STARTUP] No .env file found (this is OK in Docker): {}", e);
|
println!("[1/7] No .env file found (OK in Docker)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("[STARTUP] Initializing logging...");
|
println!("[2/7] Initializing logging...");
|
||||||
|
|
||||||
tracing_subscriber::fmt()
|
tracing_subscriber::fmt()
|
||||||
.with_env_filter(
|
.with_env_filter(
|
||||||
tracing_subscriber::EnvFilter::try_from_default_env()
|
tracing_subscriber::EnvFilter::try_from_default_env()
|
||||||
|
|
@ -41,11 +53,10 @@ async fn main() -> anyhow::Result<()> {
|
||||||
)
|
)
|
||||||
.init();
|
.init();
|
||||||
|
|
||||||
println!("[STARTUP] Loading configuration...");
|
println!("[3/7] Loading configuration...");
|
||||||
|
|
||||||
let config = match Config::from_env() {
|
let config = match Config::from_env() {
|
||||||
Ok(cfg) => {
|
Ok(cfg) => {
|
||||||
println!("[STARTUP] Config loaded: DB={}, Port={}", cfg.database.database, cfg.server.port);
|
println!("[3/7] Config loaded: DB={}, Port={}", cfg.database.database, cfg.server.port);
|
||||||
cfg
|
cfg
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
|
@ -54,11 +65,10 @@ async fn main() -> anyhow::Result<()> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
println!("[STARTUP] Connecting to MongoDB at {}...", config.database.uri);
|
println!("[4/7] Connecting to MongoDB at {}...", config.database.uri);
|
||||||
|
|
||||||
let db = match db::MongoDb::new(&config.database.uri, &config.database.database).await {
|
let db = match db::MongoDb::new(&config.database.uri, &config.database.database).await {
|
||||||
Ok(db) => {
|
Ok(db) => {
|
||||||
println!("[STARTUP] MongoDB connection successful!");
|
println!("[4/7] MongoDB connection successful!");
|
||||||
db
|
db
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
|
@ -67,11 +77,10 @@ async fn main() -> anyhow::Result<()> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
println!("[STARTUP] Performing health check...");
|
println!("[5/7] Performing health check...");
|
||||||
|
|
||||||
match db.health_check().await {
|
match db.health_check().await {
|
||||||
Ok(health) => {
|
Ok(_) => {
|
||||||
println!("[STARTUP] MongoDB health check: {}", health);
|
println!("[5/7] MongoDB health check: OK");
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
println!("[FATAL] MongoDB health check failed: {}", e);
|
println!("[FATAL] MongoDB health check failed: {}", e);
|
||||||
|
|
@ -79,6 +88,7 @@ async fn main() -> anyhow::Result<()> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
println!("[6/7] Building application...");
|
||||||
let jwt_service = auth::JwtService::new(config.jwt.clone());
|
let jwt_service = auth::JwtService::new(config.jwt.clone());
|
||||||
|
|
||||||
let app_state = config::AppState {
|
let app_state = config::AppState {
|
||||||
|
|
@ -87,8 +97,6 @@ async fn main() -> anyhow::Result<()> {
|
||||||
config: config.clone(),
|
config: config.clone(),
|
||||||
};
|
};
|
||||||
|
|
||||||
println!("[STARTUP] Building router...");
|
|
||||||
|
|
||||||
let public_routes = Router::new()
|
let public_routes = Router::new()
|
||||||
.route("/health", get(handlers::health_check))
|
.route("/health", get(handlers::health_check))
|
||||||
.route("/ready", get(handlers::ready_check))
|
.route("/ready", get(handlers::ready_check))
|
||||||
|
|
@ -102,21 +110,17 @@ async fn main() -> anyhow::Result<()> {
|
||||||
);
|
);
|
||||||
|
|
||||||
let protected_routes = Router::new()
|
let protected_routes = Router::new()
|
||||||
// Profile management
|
|
||||||
.route("/api/users/me", get(handlers::get_profile))
|
.route("/api/users/me", get(handlers::get_profile))
|
||||||
.route("/api/users/me", put(handlers::update_profile))
|
.route("/api/users/me", put(handlers::update_profile))
|
||||||
.route("/api/users/me", delete(handlers::delete_account))
|
.route("/api/users/me", delete(handlers::delete_account))
|
||||||
// Account settings
|
|
||||||
.route("/api/users/me/settings", get(handlers::get_settings))
|
.route("/api/users/me/settings", get(handlers::get_settings))
|
||||||
.route("/api/users/me/settings", put(handlers::update_settings))
|
.route("/api/users/me/settings", put(handlers::update_settings))
|
||||||
.route("/api/users/me/change-password", post(handlers::change_password))
|
.route("/api/users/me/change-password", post(handlers::change_password))
|
||||||
// Share management (Phase 2.5)
|
|
||||||
.route("/api/shares", post(handlers::create_share))
|
.route("/api/shares", post(handlers::create_share))
|
||||||
.route("/api/shares", get(handlers::list_shares))
|
.route("/api/shares", get(handlers::list_shares))
|
||||||
.route("/api/shares/:id", get(handlers::get_share))
|
.route("/api/shares/:id", get(handlers::get_share))
|
||||||
.route("/api/shares/:id", put(handlers::update_share))
|
.route("/api/shares/:id", put(handlers::update_share))
|
||||||
.route("/api/shares/:id", delete(handlers::delete_share))
|
.route("/api/shares/:id", delete(handlers::delete_share))
|
||||||
// Permissions (Phase 2.5)
|
|
||||||
.route("/api/permissions/check", post(handlers::check_permission))
|
.route("/api/permissions/check", post(handlers::check_permission))
|
||||||
.layer(
|
.layer(
|
||||||
ServiceBuilder::new()
|
ServiceBuilder::new()
|
||||||
|
|
@ -130,13 +134,12 @@ async fn main() -> anyhow::Result<()> {
|
||||||
|
|
||||||
let app = public_routes.merge(protected_routes).with_state(app_state);
|
let app = public_routes.merge(protected_routes).with_state(app_state);
|
||||||
|
|
||||||
println!("[STARTUP] Binding to {}:{}...", config.server.host, config.server.port);
|
println!("[7/7] Starting server on {}:{}...", config.server.host, config.server.port);
|
||||||
|
|
||||||
let listener = tokio::net::TcpListener::bind(&format!("{}:{}", config.server.host, config.server.port))
|
let listener = tokio::net::TcpListener::bind(&format!("{}:{}", config.server.host, config.server.port))
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
println!("[STARTUP] Server listening on http://{}:{}", config.server.host, config.server.port);
|
println!("=== SERVER READY ===");
|
||||||
println!("[STARTUP] Server ready to accept connections!");
|
println!("Listening on http://{}:{}", config.server.host, config.server.port);
|
||||||
|
|
||||||
tracing::info!("Server listening on {}:{}", config.server.host, config.server.port);
|
tracing::info!("Server listening on {}:{}", config.server.host, config.server.port);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue