Skip to content

Commit

Permalink
feat: Added tryCatch() function
Browse files Browse the repository at this point in the history
  • Loading branch information
joanllenas committed Dec 8, 2019
1 parent 52c4aea commit d1f9b23
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 5 deletions.
17 changes: 15 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ withDefault(left(new Error('Wrong!')), 0); // 0

### caseOf

`<A, B>(caseof: {Right: (v: A) => B; Left: (v: Error) => any;}, value: Either<A>): Promise<B>`
`caseOf<A, B>(caseof: {Right: (v: A) => B; Left: (v: Error) => any;}, value: Either<A>): Promise<B>`

Run different computations depending on whether an `Either` is `Right` or `Left` and returns a `Promise`

Expand All @@ -159,7 +159,7 @@ caseOf(

### map

`<A, B>(f: (a: A) => B, value: Either<A>): Either<B>`
`map<A, B>(f: (a: A) => B, value: Either<A>): Either<B>`

Transforms an `Either` value with a given function.

Expand All @@ -169,6 +169,19 @@ map(add1, right(4)); // Right<number>(5)
map(add1, left(new Error('Something bad happened'))); // Left('Something bad happened')
```

### tryCatch

`tryCatch<A>(f: () => A, onError: (e: Error) => Error): Either<A>`

Transforms a function (that might throw an exception) that produces `A` to a function that produces `Either<A>`.

```ts
tryCatch(
() => JSON.parse(''),
err => err
); // Left('Unexpected end of JSON input')
```

### andThen

`andThen<A, B>(f: (a: A) => Either<B>, value: Either<A>): Either<B>`
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ts.data.either",
"version": "1.0.0",
"version": "2.1.0",
"description": "A Typescript implementation of the Either data type",
"main": "dist/index.js",
"types": "dist/index.d.ts",
Expand Down
45 changes: 44 additions & 1 deletion src/either.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import {
map,
andThen,
Either,
caseOf
caseOf,
tryCatch
} from './either';

import * as chai from 'chai';
Expand Down Expand Up @@ -163,6 +164,32 @@ describe('Either', () => {
});
});

describe('tryCatch', () => {
let shouldFail: boolean;
const fn = () => {
if (shouldFail) {
throw anError();
}
return 'Ok';
};
it('should convert a failing function into a Left', () => {
shouldFail = true;
return expect(
caseOf(
{
Left: err => `Error: ${err.message}`,
Right: n => `Launch ${n} missiles`
},
tryCatch(fn, err => err)
)
).to.be.rejectedWith('Error: Something is wrong');
});
it('should convert a successful function into a Right', () => {
shouldFail = false;
expect(tryCatch(fn, err => err)).to.deep.equal(right('Ok'));
});
});

describe('examples', () => {
type Band = {
artist: string;
Expand Down Expand Up @@ -237,5 +264,21 @@ describe('Either', () => {
)
).to.be.rejectedWith(`Unexpected end of JSON input`);
});

it('should be a good tryCatch example', () => {
const res = tryCatch(
() => JSON.parse(''),
err => err
);
return expect(
caseOf(
{
Left: err => err.message,
Right: result => result
},
res
)
).to.be.rejectedWith(`Unexpected end of JSON input`);
});
});
});
11 changes: 11 additions & 0 deletions src/either.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,14 @@ export const caseOf = <A, B>(
return Promise.resolve(caseof.Right((value as Right<A>)._value));
}
};

export const tryCatch = <A>(
f: () => A,
onError: (e: Error) => Error
): Either<A> => {
try {
return right(f());
} catch (e) {
return left(onError(e));
}
};
3 changes: 2 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ export {
withDefault,
map,
andThen,
caseOf
caseOf,
tryCatch
} from './either';

0 comments on commit d1f9b23

Please sign in to comment.