@gcanti I've been using something like this in my applications. Do you think it could be added to the library?
export function eitherTryCatchAsync<E, A>(f: Lazy<Promise<A>>): Promise<Either<E, A>> {
try {
return f().then(a => either.right<E, A>(a), e => either.left<E, A>(e));
} catch (e) {
return Promise.resolve(either.left<E, A>(e));
}
}
@OliverJAsh the signature is a bit weird
E? (indeed since e: any then e => either.left<E, A>(e) and Promise.resolve(either.left<E, A>(e)) are basically unsafe casts)What about
function tryCatchAsync<E, A>(p: Lazy<Promise<A>>, onerror: (reason: any) => E): Lazy<Promise<Either<E, A>>>
@gcanti Good improvements. That works for me!
So:
import * as either from 'fp-ts/lib/Either';
import { Lazy } from 'fp-ts/lib/function';
import Either = either.Either;
export const eitherTryCatchAsync = <E, A>(
f: Lazy<Promise<A>>,
onError: (reason: any) => E,
): Lazy<Promise<Either<E, A>>> => () => {
try {
return f().then(a => either.right<E, A>(a), reason => either.left<E, A>(onError(reason)));
} catch (e) {
return Promise.resolve(either.left<E, A>(e));
}
};
I wonder, what the try..catch is for? AFAIK both f(), a => either.right<E, A>(a) can't fail
So basically is this right? https://github.com/gcanti/fp-ts/blob/92bc1ed617597a4ba8246d859d97a470be31b1ad/examples/TaskEither.ts#L75
@gcanti I believe f could throw. For example:
const someFnThatThrowsSynchronously = () => {
throw new Error();
}
const fn: Lazy<Promise<string>> = () => {
someFnThatThrowsSynchronously();
return Promise.resolve('foo');
}
Ah, I see. Though ideally a possible failure should be encoded in the type system (with Option/Either).
So shouldn't fn be responsible of handling a possible error? Either changing the signature
const someFnThatThrowsSynchronously = () => {
throw new Error();
}
const fn: Lazy<Option<Promise<string>>> = () => {
try {
someFnThatThrowsSynchronously();
return some(Promise.resolve('foo'))
} catch (e)Â {
return none
}
}
or rejecting the promise
const someFnThatThrowsSynchronously = () => {
throw new Error();
}
const fn: Lazy<Option<Promise<string>>> = () => {
try {
someFnThatThrowsSynchronously();
return Promise.resolve('foo')
} catch (e)Â {
return Promise.reject(e)
}
}
I see. You could have a higher-order function that normalizes promise-returning functions so any exceptions are returned as rejected promises. Then, the resulting function could be passed into tryCatchAsync (without a try/catch around fn).
I think it is identical to taskEither.fromPromise, except I think there should be some flexibility in the return value:
Promise<Either<L, A>> — perhaps this could be provided by either?Task<Either<L, A>> — perhaps this could be provided by task?TaskEither<L, A>— this is already provided by taskEither(*) Either would contain a function coupled with a Promise implementation (see https://github.com/gcanti/fp-ts/issues/87). @leemhenson what do you think? Any suggestion?
Hi. I have small question: I need to do fetch and then validate response with io-ts. Is there more elegant way to do this, then
request()
.then(result =>
result.fold(
error => store.dispatch(Failed()),
data => store.dispatch(Ok(data))
)
)
.catch(error => store.dispatch(Failed()));
export const getJson = (url: string) => {
return new task.Task(() => fetch(url))
.map(parseJsonFromResponse)
.map(requierRootObject);
};
export const request = () => {
return getJson(`/api/prices.json`)
.map(decodePriceResponse) //
.run();
};
// PriceInterface is io-ts type
export const decodePriceResponse = (obj: {}) => t.validate(obj, PriceInterface);
I was not able to figure out how to use the library to handle async/await for third party libraries that do not use fp-ts. Below function works for me. I am not sure if it is the FP way, however. Can anyone suggest a better approach @OliverJAsh @gcanti @stereobooster ?
export async function eitherTryCatchAsync<E, A>(
f: () => Promise<A>,
): Promise<either.Either<E, A>> {
try {
let result = await f();
return Promise.resolve(either.right<E, A>(result))
} catch (reason) {
return Promise.resolve(either.left<E, A>(reason))
}
};
@navinkumarr usually the FP way is to prefer Task to Promise
I would prefer to use Observables and use RxJs Bindings
On Sun, 21 Oct 2018, 22:16 navinkumarr, notifications@github.com wrote:
I was not able to figure out how to use the library to handle async/await
for third party libraries that do not use fp-ts. Below function works for
me. I am not sure if it is the FP way, however. Can anyone suggest a better
approach @OliverJAsh https://github.com/OliverJAsh @gcanti
https://github.com/gcanti @stereobooster
https://github.com/stereobooster ?export async function eitherTryCatchAsync
(
f: () => Promise,
): Promise> {
try {
let result = await f();
return Promise.resolve(either.right(result))
} catch (reason) {
return Promise.resolve(either.left(reason))
}
};—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/gcanti/fp-ts/issues/159#issuecomment-431684241, or mute
the thread
https://github.com/notifications/unsubscribe-auth/AO6DzNaoI4p4QSJGWmMpRIrxIb8qRuu-ks5unKTJgaJpZM4ObzmL
.
You can just take a look at fp-ts-rxjs
There is currently no tryCatch function for rxjs but you can build your own one:
const tryCatch = <L, R>(f: () => Promise<R>): Observable<Either<L, R>> =>
defer(f).pipe(
map((r) => right<L, R>(r)),
catchError((l) => of(left<L, R>(l)))
);