Skip to content

Instantly share code, notes, and snippets.

@rendall

rendall/apiPromise.ts

Last active Oct 18, 2020
Embed
What would you like to do?
API Promise replaces node-fetch
import * as dotenv from "dotenv"
import * as http from "https"
import { IncomingMessage, ClientRequest } from "http"
dotenv.config()
const API_KEY = process.env.API_KEY
const API_HOST = process.env.API_HOST
const API_PATH = process.env.API_PATH
const TIMEOUT_MS = 5000
const TIMEOUT_ERROR_STATUS_CODE = 504 // As a const, to clarify meaning of '504'
const apiPromise = (endpoint: string) => new Promise((resolve, reject) => {
const hostname = `${API_HOST}`
const path = `${API_PATH}/${endpoint}`
const auth = `${API_KEY}:`
const requestOptions: http.RequestOptions = { hostname, path, auth }
const onResponse = (res: IncomingMessage) => {
const { statusCode, statusMessage } = res
if (!statusCode || statusCode !== 200) reject({ statusCode, statusMessage })
res.on("error", (error) => {
console.error(`${endpoint} error`, error)
res.resume()
reject({ statusCode, statusMessage })
})
let dump = ""
res.on("data", data => (dump += data))
res.on("end", () => {
try {
const json = JSON.parse(dump)
resolve(json)
} catch (error) {
reject({ statusCode: 500, statusMessage: `${error.name}: ${error.message}` })
}
})
}
const request: ClientRequest = http.get(requestOptions, onResponse)
const onTimeout = () => request.abort()
const onRequestError = (error: Error) => {
switch (error.message) {
case "socket hang up":
if (request.aborted) {
reject({ statusCode: TIMEOUT_ERROR_STATUS_CODE, statusMessage: "request timeout" })
break
}
default:
reject({ statusCode: 500, statusMessage: `${error.name}: ${error.message}` })
break
}
}
request.addListener("error", onRequestError)
request.setTimeout(TIMEOUT_MS, onTimeout)
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.