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?
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 String
s using BufReader
everything in it has to be valid UTF-8.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With