snag icon indicating copy to clipboard operation
snag copied to clipboard

utility function for converting from arbitrary errors

Open aslilac opened this issue 2 years ago • 2 comments

it'd be nice to have something like...

pub fn convert(tried: Result(a,b)) -> Snag(a) {
  tried
  |> result.map_error(fn(e) {
    e
    |> string.inspect()
    |> error()
  })
}

for quickly turning any error into a Snag

aslilac avatar Dec 19 '23 06:12 aslilac

alternatively could be named from or something

aslilac avatar Dec 19 '23 06:12 aslilac

This would result in very poor error messages so I'm not sure this is a good idea. It won't have any information written for humans, and it could contain data of any size and shape.

lpil avatar Dec 19 '23 09:12 lpil

Hello! Love this package. Simplifile has a describe_error function (and I am working on adding the same to tempo) which nicely transforms an error into human readable text. This seems like a useful pattern for me, and could go really well with snag, hopefully encouraging other packages to implement something similar. What do you think about adding a function that uses a library's error describing function to do a very similar thing to what was originally posted here? It could be used like:

import simplifile
import snag

pub fn main() {
  let file_path = "fun_file.txt"

  simplifile.read(file_path)
  |> snag.convert(with: simplifile.describe_error)
  |> snag.context("Error reading file " <> file_path)
}

The definition could be something like:

pub fn convert(
  res: Result(a, b),
  with describer: fn(b) -> String,
) -> Result(a, snag.Snag) {
  case res {
    Ok(v) -> Ok(v)
    Error(e) -> Error(snag.new(describer(e)))
  }
}

Without a function like this, we can achieve the same thing but with a lot of extra symbols:

import gleam/result
import simplifile
import snag

pub fn main() {
  let file_path = "fun_file.txt"

  simplifile.read(file_path)
  |> result.map_error(fn(e) { snag.new(simplifile.describe_error(e)) })
  |> snag.context("Error reading file " <> file_path)
}

I use snag a lot for snowballing errors into logs, and the biggest pain point of the package is just massaging all other error types into a string to create a new snag with. This function would make that very frequent task a lot nicer :)

The name and signature are up for discussion, but I am happy to write tests and documentation on it if you think it fits.

jrstrunk avatar Dec 17 '24 13:12 jrstrunk

Sounds like a really good idea to me! I'm not entirely sure about the name convert, but we can bikeshed on that one.

lpil avatar Dec 17 '24 13:12 lpil

Great!

For different semantics, what do you think of translate, transform, rephrase, summarize, digest, or conclude? (just brainstorming)

For better clarity, what do you think of something along the lines of snag.map_error, snag.convert_error, snag.from_error, snag.translate_error?

Some version of this might look like:

import simplifile
import snag

pub fn main() {
  let file_path = "fun_file.txt"

  simplifile.read(file_path)
  |> snag.map_error(with: simplifile.describe_error)
  |> snag.context("Error reading file " <> file_path)
}

jrstrunk avatar Dec 17 '24 14:12 jrstrunk

Ah very nice! map_error seems like it would be very understandable to anyone who has used the result module, which is probably most Gleam developers!

lpil avatar Dec 17 '24 14:12 lpil

Fantastic! I think so too, I'll try to write tests and documentation for it later today or tomorrow and open a PR. Thanks!

jrstrunk avatar Dec 17 '24 14:12 jrstrunk

Thank you!

lpil avatar Dec 17 '24 14:12 lpil