Skip to content

Commit

Permalink
Enhanced early crashing on for example db connect failure (#45)
Browse files Browse the repository at this point in the history
* Enhanced early crashing on for example db connect failure

* Also better returns on the connection fn

* More complete error reporting when setup fail

* Rename `c` to `setup` for clarity

* I never even considered file access errors.

* Update backend/src/lumina.gleam

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Ensure 'start_l' returns an error when directory creation fails

* Update backend/src/lumina.gleam

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Remove never-returned `Ok(Nil)`

* Add in inspection of error message.

* Better erroring

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
  • Loading branch information
strawmelonjuice and coderabbitai[bot] authored Nov 18, 2024
1 parent 240889f commit 1323bc9
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 41 deletions.
64 changes: 42 additions & 22 deletions backend/src/lumina.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -50,56 +50,69 @@ pub fn main() {
}

fn start_def() {
let home = case gleamyshell.home_directory() {
Ok(home) -> home
case gleamyshell.home_directory() {
Ok(home) -> start(string.replace(home, "\\", "/") <> "/.luminainstance/")
Error(e) -> {
let a = "Could not load the user folder" <> string.inspect(e)
panic as a
{ "Could not load the user folder" <> string.inspect(e) }
|> wisp.log_critical
}
}
start(string.replace(home, "\\", "/") <> "/.luminainstance/")
}

fn start(in: String) {
case start_l(in) {
Ok(Nil) -> Nil
Error(e) -> {
io.println_error(
premixed.text_dark_black(premixed.bg_error_red("FAIL")) <> ": " <> e,
)
Nil
}
}
}

fn start_l(in: String) -> Result(Nil, String) {
use <- bool.lazy_guard(
when: bool.and(
os.family() == os.WindowsNt,
bool.negate(list.contains(argv.load().arguments, "--allow-windows")),
),
return: fn() {
io.println(premixed.text_error_red(
"Lumina does not run correctly on Windows yet. Please use WSL for now, or be brave and use the '--allow-windows' flag.",
Error(premixed.text_error_red(
"Lumina does not run correctly on Windows yet. Please use WSL or use the '--allow-windows' flag to run Lumina on Windows.",
))
Nil
},
)
// Configure erlang logger.
wisp.configure_logger()
// Check if environment exists
case fs.is_directory(in) {
Ok(True) -> Nil
Ok(False) -> {
use exists <- result.try(result.replace_error(
fs.is_directory(in),
"Could not check whether the selected directory exists.",
))

use _ <- result.try(case exists {
True -> Ok(Nil)
False -> {
case fs.create_directory(in) {
Error(_) -> {
wisp.log_critical("Directory '" <> in <> "' cannot be written.")
Error("Failed to create directory '" <> in <> "'.")
}
Ok(_) -> Nil
Ok(_) -> Ok(Nil)
}
}
Error(_) -> {
wisp.log_critical("Directory '" <> in <> "' cannot be read.")
}
}
})
// Load environment
let lumina_config = config.load(in)

// Set a secret_key_base
let secret_key_base = wisp.random_string(64)
let priv_directory = get_priv_directory()
// Connect to database
let dbc = database.connect(lumina_config, in)
// Sets up database in case of need.
database.c(dbc)
use dbc <- result.try(database.connect(lumina_config, in))

// Sets up database in case of need. Exits on error.
use _ <- result.try(database.setup(dbc))

// Set up session store
let assert Ok(actor_store) = actor_store.try_create_session_store()
Expand Down Expand Up @@ -135,12 +148,19 @@ fn start(in: String) {
// Add context to handler
let handler = routing.handle_request(_, ctx)

let assert Ok(_) =
case
wisp.mist_handler(handler, secret_key_base)
|> mist.new
|> mist.port(ctx.config.lumina_server_port)
|> mist.start_http
process.sleep_forever()
{
Ok(_) -> {
Ok(process.sleep_forever())
}
Error(e) -> {
Error("Failed to start server: " <> string.inspect(e))
}
}
}

fn get_priv_directory() -> String {
Expand Down
47 changes: 28 additions & 19 deletions backend/src/lumina/database.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -16,31 +16,39 @@ pub type LuminaDBConnection {
SQLiteConnection(String)
}

pub fn connect(lc: LuminaConfig, in: String) -> LuminaDBConnection {
pub fn connect(
lc: LuminaConfig,
in: String,
) -> Result(LuminaDBConnection, String) {
case lc.db_connection_info {
LuminaDBConnectionInfoPOSTGRES(config) -> {
wisp.log_info("Connecting to Postgres database...")
pog.connect(config)
|> POSTGRESConnection
Ok(
pog.connect(config)
|> POSTGRESConnection,
)
}
LuminaDBConnectionInfoSQLite(file_) -> {
// Always relative to the instance folder.
let file = in <> "/" <> file_
wisp.log_info("Connecting to SQLite database...")
let conn = case sqlight.open(file) {
Ok(connection) -> connection
case sqlight.open(file) {
Ok(connection) -> {
use _ <- result.try(result.replace_error(
sqlight.close(connection),
"Could not close SQLite connection for later usage.",
))
Ok(SQLiteConnection(file))
}
Error(e) -> {
wisp.log_critical("SQLite Connection error: " <> e.message)
panic
Error("SQLite Connection error: " <> e.message)
}
}
let assert Ok(_) = sqlight.close(conn)
SQLiteConnection(file)
}
}
}

pub fn c(connection: LuminaDBConnection) {
pub fn setup(connection: LuminaDBConnection) -> Result(Nil, String) {
case connection {
POSTGRESConnection(con) -> {
let result =
Expand Down Expand Up @@ -78,15 +86,16 @@ pub fn c(connection: LuminaDBConnection) {
|> pog.execute(con)
})
case result {
Ok(_) -> Nil
Ok(_) -> Ok(Nil)
Error(e) -> {
wisp.log_info(
text_error_red("Error creating tables in PostGres. ")
Error(
text_error_red("PostgreSQL Table Creation Failed:\n")
<> string.inspect(e)
<> "\n\n"
<> text_lime(
"Some tips: \r\n\t- are the environment variables set correctly?\n\t - Is PostGres up and running?",
"Some tips:\r\n\t- are the environment variables set correctly?\n\t - Is PostGres up and running?",
),
)
wisp.log_error(string.inspect(e))
}
}
}
Expand Down Expand Up @@ -128,16 +137,16 @@ CREATE TABLE IF NOT EXISTS users(
)
{
Ok(_) -> {
Nil
Ok(Nil)
}
Error(e) -> {
wisp.log_info(
wisp.log_error(string.inspect(e))
Error(
text_error_red("Error creating tables in SQLite. ")
<> text_lime(
"Some tips: \r\n\t- are the environment variables set correctly?\n\t - Does the file already exist with corrupt data?",
"Some tips: \r\n\t- are the environment variables set correctly?\n\t- Does the file already exist with corrupt data?\n\t- Check if the process has write permissions to the database file",
),
)
wisp.log_error(string.inspect(e))
}
}
}
Expand Down

0 comments on commit 1323bc9

Please sign in to comment.