Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rust dotenv isn't able to read .env file

Tags:

rust

dotenv

I've got a Rust test app that uses dotenv. It's supposed to read a few keys in a .env file located at the project source folder. This is how my main function starts, calling dotenv and reading one of the keys, printing and logging it with a handmade script that handles it:

// Depdendencies
use actix_web::{web, App, HttpServer};
use diesel::r2d2::{ConnectionManager, Pool};
use diesel::sqlite::SqliteConnection;
use dotenvy::dotenv;


// Modules import
mod utils;
use utils::*;
mod models;
mod schema;
mod api_modules;
use api_modules::{
    books_handlers, books_relationships_handlers, users_handlers,
};

#[actix_rt::main]
async fn main() -> std::io::Result<()> {
    // Load .env file and set initialization variables
    dotenv().ok();
    log(LogType::Info, "Starting server...".to_string());

    // more code, API initialization, etc

The code seems to break at the log function, imported from the utils module. That module is mostly empty, but it's there to wrap all the utility code that doesn't fall into an API categorization. For now, it looks like this:

mod logger;

pub use logger::*;

The logger exposes the log function, which makes use of three more functions (craft_message, write_to_console, write_to_logfile). They are simple enough not to be added here in order to not clutter the post.

The problem seems to be in write_to_logfile, when I try to read the LOG_FILE key from the .env file:

fn write_to_logfile(message: &String) {
    let path: String = std::env::var("LOG_FILE").expect("LOG_FILE must be set"); 
    let mut file = OpenOptions::new()
        .write(true)
        .append(true)
        .open(&path)
        .unwrap();

    if let Err(e) = writeln!(file, "{}", message) {
        eprintln!("Couldn't write to file: {}", e);
    }
}

This is the error:

     Running `target\debug\rust_web_server.exe`
2023-03-25, Marh:03m - [Info] - Starting server...
thread 'main' panicked at 'LOG_FILE must be set: NotPresent', src\utils\logger.rs:41:50

What is the problem here? I thought that calling dotenv().ok() in the start of the main file was enough to read keys from a file and set them as environment variables. This is how my file looks:

DATABASE_URL=db
LOG_FILE=logs.txt

It's located at the same folder as the main.rs file, so... what's the problem here?

like image 266
Zerok Avatar asked Sep 13 '25 08:09

Zerok


1 Answers

It's located at the same folder as the main.rs file, so... what's the problem here?

That's exactly the problem, according to the usage dotenv()

will load environment variables from a file named .env in the current directory or any of its parents;

that is the working directory of the program at runtime, with cargo run that's the folder where the Cargo.toml is.

Additionally the format is without trailing semicolons:

DATABASE_URL=db
LOG_FILE=logs.txt

You should also make sure .env is a plain text file, not containing any non-UTF-8 characters, since dotenv loads into Strings using BufReader everything in it has to be valid UTF-8.

like image 104
cafce25 Avatar answered Sep 14 '25 21:09

cafce25