DEV Community

Discussion on: Handling errors with Either

Collapse
 
normancarcamo profile image
Norman Enmanuel

Wow, it's good to see more people in FP these days!, more collaboration is always welcome.
Btw, how would you handle sync/async + composition?
It's a bit hard to handle all these concepts together in JS, in Elixir or Scala I don't see too much problem due to their nature.

Thanks!.

Collapse
 
avalander profile image
Avalander

Thanks for the comment :)

Btw, how would you handle sync/async + composition?

That's a good question. Unfortunately, I don't have a good answer.

Sometimes I just use promises as pseudo-either monads when I have to mix sync and async code and that's good enough.

// Instead of throwing an exception with invalid JSON,
// this function will capture it in a promise's rejection branch.
const parseJson = data => Promise.resolve(data)
    .then(JSON.parse)

// Another sync function wrapped in a promise.
const verifyResponse = ({ statusCode, body }) =>
    statusCode === 200
        ? Promise.resolve(body)
        : Promise.reject({ statusCode, body })

parseJson(someData) // For some weird reason our data is stringified JSON, very convenient to manipulate.
    .then(postData) // We send our data to a remote host
    .then(verifyResponse) // We verify that we get 200 back
    .then(parseJson) // We parse the body of the response
    // ...

Another option would be to map eithers and maybes to promises when composing sync and async functions.

const Left = x => ({
    ...
    toPromise: () => Promise.reject(x),
})

const Right = x => ({
    ...
    toPromise: () => Promise.resolve(x),
})

const map = F => x => F.map(x)
const chain = F => x => F.chain(x)
const toPromise = F => F.toPromise()

const parseJson = data => tryCatch(JSON.parse, data)

const verifyResponse = ({ statusCode, body }) =>
    statusCode === 200
        ? Right(body)
        : Left({ statusCode, body })

parseJson(someData)
    .toPromise()
    .then(postData) // We send our data to a remote host
    .then(verifyResponse) // We verify that we get 200 back
    .then(chain(parseJson)) // In case you want to keep the Either inside the promise
    .then(toPromise) // In case you want to unwrap the Either

Most of the times I think promises as pseudo-eithers is good enough, so I haven't explored how to compose them with proper eithers that much.

Collapse
 
normancarcamo profile image
Norman Enmanuel

Thanks for reply!

I actually used to do what you mention in the first code example, but not in the last example (nice trick to explicitly and descriptively passing from sync to async), at the end of the day when we enter to the async world we cannot exit, even worse, they can be nested, but luckily we have async/await mechanism to flat it.

By the way, I think the operator pipe will fix this.