Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/bendyworks/rah-rah
Use await while respecting failure cases without exceptions
https://github.com/bendyworks/rah-rah
await javascript promise typescript typescript-library
Last synced: 28 days ago
JSON representation
Use await while respecting failure cases without exceptions
- Host: GitHub
- URL: https://github.com/bendyworks/rah-rah
- Owner: bendyworks
- License: apache-2.0
- Created: 2018-02-09T20:33:04.000Z (almost 7 years ago)
- Default Branch: master
- Last Pushed: 2022-12-29T08:45:08.000Z (almost 2 years ago)
- Last Synced: 2024-11-02T21:49:54.871Z (about 2 months ago)
- Topics: await, javascript, promise, typescript, typescript-library
- Language: JavaScript
- Size: 490 KB
- Stars: 0
- Watchers: 6
- Forks: 0
- Open Issues: 25
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# RahRah
Use Javascript `await` while respecting failure cases without exceptions.
## Why does this exist?
If you want to use `await` and still get data from failure cases, you must use `try/catch`:
```typescript
// old wayasync function myFunc() {
let result;
try {
result = await someAsyncFunc();
doSomething(result);
} catch (e) {
handleError(e);
}
}// new way with rah-rah
import { R } from 'rah-rah';
async function myFunc() {
const result = await R(someAsyncFunc());if (result.good) {
doSomething(result.ok);
} else {
handleError(result.err);
}
}// or even
import { R } from 'rah-rah';
async function myFunc(): string {
const result = await R(someAsyncFunc());return (
result
.map(doSomething)
.mapErr(handleError)
.withDefault('n/a')
);
}
```If you recognize this kind of thing from the Functional Programming world, it's basically Result/Either mapped inside a Promise... or something like that.
## Usage
A simple example app is available in the `examples` folder.
### Creation
Insert a call to `R` between `await` and your promise:
```typescript
import { R } from 'rah-rah';const result = await R(aPromise);
const otherResult = await R(ajaxAsPromise(url));
```### Did it fail or succeed?
If you use `withDefault`, `map`, and `mapErr` (shown below), you shouldn't
need these.```typescript
import { R } from 'rah-rah';async function go(aPromise: Promise<...>) {
const result = await R(aPromise);
if (result.good) {
// ...
} else { ... }// or
if (result.bad) {
// ...
}
}
```### Raw results
Use `result.ok` and `result.err`. If you use `withDefault`, `map`, and `mapErr`
(shown below), you shouldn't need these.```typescript
import { R } from 'rah-rah';async function go(aPromise: Promise<...>) {
const result = await R(aPromise);
if (result.good) {
doSomething(result.ok);
} else { ... }// or
if (result.bad) {
handleError(result.err);
}
}
```### Collapsing errors
Perhaps you don't care about an error? Or you've correctly handled the error,
and you'd like to use either a successful value or a default value in the case
of a failure:```typescript
import { R } from 'rah-rah';async function go(aPromise: Promise): Promise {
const result = await R(aPromise);
return result.withDefault('An error occurred.');
}
```If you want the default to use the underlying error value, use `applyDefault`:
```typescript
import { R } from 'rah-rah';async function go(aPromise: Promise): Promise {
const result = await R(aPromise);
return result.applyDefault((err: Error) => `An error of type '${err.name}' occurred.`);
}
```### Changing ("map"ing) successful values
Need to change ("map") the successful value? Use `map`:
```typescript
import { R } from 'rah-rah';async function go(aPromise: Promise): Promise> {
const result = await R(aPromise);
return result.map(ok => `answer: ${ok}`); // still wrapped in a RahRah object!
}
```### Changing ("map"ing) failure values
Need to change ("map") the failure value? Use `mapErr`:
```typescript
import { R } from 'rah-rah';async function go(aPromise: Promise): Promise> {
const result = await R(aPromise);
return result.mapErr(err => err.message.toLowerCase()); // still wrapped in a RahRah object!
}
```### Collapsing errors & results
Perhaps you need to do something with both successful and failure situations,
and return an unwrapped value:```typescript
import { R } from 'rah-rah';function double(result: RahRah): string {
return result.flatten(ok => {
return `doubled: ${ok * 2}`;
}, err => {
informExceptionHandler(err);
return err.message.toLowerCase();
});
}const result = await R(aPromise);
console.log(double(result));
```## Installation
This library requires TypeScript, with at least `es2015` compatibility.
$ npm install typescript --save-dev
$ npm install rah-rah --save## Other similar libraries
### await-to-js
[await-to-js][to] provides a wonderfully simple API that does _nearly_ the
same thing:```typescript
import to from 'await-to-js';const [err, user] = await to(UserModel.findById(1));
```The problem is that `await-to-js` assumes that you'll never want to use `null`
as a real error value; that is, you can never have a `null` value for `err`.
Similarly, you're disallowed from returning (as unlikely as it is) `undefined`
as your successful value.These edge cases are nuanced and very unlikely, but they exist. RahRah avoids
these edge cases.## License
License terms can be found in the LICENSE file.
## Author
RahRah was written by:
* [Brad Grzesiak](https://twitter.com/listrophy) - [Bendyworks](https://bendyworks.com)
[to]: https://github.com/scopsy/await-to-js