fetchmap
Non-throwing Fetch API wrapper
Getting started
npm i fetchmap
Description
This is a simple wrapper for a fetch
-like function that catches all possible exceptions and returns a 'success or failure' wrapped value. It takes an object that maps response.status
to validating transform and standard fetch
arguments.
Read the docs here and check how fetchmap
infers types at the playground. Also there is a compatible result library - ts-railway.
Example
Server code:
import express from 'express'
express()
.get('/data', (_, res) => {
const rnd = Math.random()
if (rnd < 0.34) {
res.status(200).json({ some: 'data' })
} else if (rnd < 0.67) {
res.status(201).send('This is not JSON!')
} else {
res.status(500).send('Server error!')
}
})
.listen(5005)
Client code:
import { createFetchmap } from 'fetchmap'
import nodeFetch, { Response } from 'node-fetch'
import { isRecord } from 'ts-is-record'
const success = <T>(value: T) => ({ tag: 'success', success: value } as const)
const failure = <T>(error: T) => ({ tag: 'failure', failure: error } as const)
const fetchmap = createFetchmap(nodeFetch)
const validateData = (body: unknown) =>
isRecord(body) && 'some' in body && typeof body.some === 'string'
? success(body)
: failure('data validation failed' as const)
const validateError = (body: string, { status }: Response) => success({ message: body, status })
const dataResult = await fetchmap(
{
ok: { json: validateData },
notOk: { text: validateError }
},
'https://localhost:5005/data',
{
}
)
expect([
{ tag: 'success', success: { some: 'data' } },
{ tag: 'failure', failure: { serverError: { message: 'Server error!', status: 500 } } },
{
tag: 'failure',
failure: { mapError: new SyntaxError('Unexpected token T in JSON at position 0') }
}
]).toContainEqual(dataResult)