glint icon indicating copy to clipboard operation
glint copied to clipboard

A question about error handling in the executed command

Open oderwat opened this issue 7 months ago • 1 comments

Am I correct that if I want to handle errors from the actual running command I needs to use run_and_handle() and handle errors myself?

This would for example need to including adding another "exit(1)" implementation.

I actually thought at first that returning Error(String) would print the string and exit(1). It also seems that I can't have anything else than Error(String) with that, where I would maybe like to use snag. So I would probably even need to add my own Result type as Ok(Result(Nil,EApp))?

I probably miss something, and it is supposed to work differently. I skimmed some other apps using Glint and found mostly "let assert ..." or panic style "error handling".

Here some code to illustrate what I mean:

pub fn main() -> Nil {
  let cmds =
    glint.new()
    |> glint.with_name(tomlvars.name)
    |> glint.add(at: [], do: run())
  use out <- glint.run_and_handle(cmds, argv.load().arguments)
  case out {
    Error(err) -> {
      io.print_error("Error: " <> err)
      exit(1)
    }
    _ -> Nil
  }
}

fn run() -> glint.Command(Result(Nil, String)) {
  use <- glint.command_help("import a csv to the welo marktordnung")
  use <- glint.unnamed_args(glint.EqArgs(0))
  use arg_csv <- glint.named_arg("csv")
  use arg_periode <- glint.named_arg("periode")
  use named, _unnamed, _flags <- glint.command()

  // if this fails it will end up in the `case out` above and has to be `Error(String)`
  use csv_data <- result.try(read_csv(arg_csv(named)))

  // same with this
  use periode <- result.try(welo.parse_dbdate(arg_periode(named)))

  let con = connect()
  echo csv_data
  echo periode
  echo con
  Ok(Nil)
}

@external(erlang, "erlang", "halt")
@external(javascript, "node:process", "exit")
fn exit(status: Int) -> Nil

oderwat avatar May 26 '25 22:05 oderwat

Hi there! Currently, glint has no way to know what to do with the return type of your command without you telling it via run_and handle — since it can be anything, and glint has no way of knowing currently that your commands return a Result. This is because the Result output of glint reflects whether or not glint was able to execute, not whether or not your command function succeeded. I have considered adding some convenience functionality in the cases where commands return a Result(a, String) or Result(a, Snag) so this does give me a bit to think about.

That said, I am in the process of rethinking this pattern a bit as I work on glint v2 so things may look different as that progresses.

TanklesXL avatar Jun 08 '25 21:06 TanklesXL