# http-as-promised

> Promisified HTTP client

Latest version **2.0.1** (published 2018-01-12) · MIT license · 0 weekly downloads

## Install

```sh
npm install http-as-promised
pnpm add http-as-promised
yarn add http-as-promised
bun add http-as-promised
```

## Health

**Score 15/100 (F)** — status: abandoned.

Positive: no vulnerabilities.

Warnings: low downloads; no types; no esm support.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 2.0.1 |
| Published | 2018-01-12 |
| First published | 2014-09-19 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | none |
| Module format | CommonJS |
| Node | >=4 |
| Dependencies | 3 |
| Known vulnerabilities | 0 (+1 in 1 direct dependencies) |
| Install scripts | no |
| GitHub stars | 3 |
| Author | James Cready |
| Maintainers | apechimp, jcready |
| Keywords | errors, exceptions, throw, custom, util, utility, bluebird, promise, request, http, https, statusCode |

## Links

- npm: https://www.npmjs.com/package/http-as-promised
- Repository: https://github.com/jcready/http-as-promised
- Issues: http://github.com/jcready/http-as-promised/issues
- npm.io page: https://npm.io/package/http-as-promised

## Dependencies (3)

- [request](https://npm.io/package/request.md) ^2.83.0
- [bluebird](https://npm.io/package/bluebird.md) ^3.5.1
- [create-error](https://npm.io/package/create-error.md) ^0.3.1

## Alternatives

- [@commercetools/sync-actions](https://npm.io/package/@commercetools/sync-actions.md) — 25.1K weekly downloads
- [cwait](https://npm.io/package/cwait.md) — 21.4K weekly downloads
- [@ledgerhq/hw-app-cosmos](https://npm.io/package/@ledgerhq/hw-app-cosmos.md) — 4.2K weekly downloads
- [@financial-times/o-loading](https://npm.io/package/@financial-times/o-loading.md) — 2.8K weekly downloads
- [fa](https://npm.io/package/fa.md) — 185 weekly downloads

## Recent versions

- 2.0.1 (latest) — 2018-01-12
- 0.0.2 (0.0.2) — 2014-09-19
- 0.0.1 (0.0.1) — 2014-09-19
- 1.1.0 — 2015-08-13
- 1.0.0 — 2015-03-06
- 0.1.0 — 2014-09-22
- 0.0.12 — 2014-09-21
- 0.0.11 — 2014-09-21
- 0.0.10 — 2014-09-21
- 0.0.9 — 2014-09-21
- 0.0.8 — 2014-09-21
- 0.0.7 — 2014-09-20
- 0.0.6 — 2014-09-20
- 0.0.5 — 2014-09-20
- 0.0.4 — 2014-09-20
- … 1 more at https://npm.io/package/http-as-promised/versions

## README

# HTTP as Promised — Promisified HTTP client.

[![NPM Version][npm-image]][npm-url]
[![Build Status][travis-image]][travis-url]
[![Test Coverage][coveralls-image]][coveralls-url]
[![Code Climate][codeclimate-image]][codeclimate-url]
[![Dependencies][dependencies-image]][dependencies-url]

Using [bluebird][bluebird] and [create-error][create-error] to make [request][request] easier to use. The most notible difference between this library and simply "promisifying" the request module is that this library will automatically reject the promise with an `HTTPError` if the response idicates an HTTP error (e.g. `response.statusCode >= 400`). HTTP as Promised supports all the same [options you'd pass to request](https://github.com/mikeal/request/blob/master/README.md#requestoptions-callback) as well as all of [request's convenience methods](https://github.com/mikeal/request/blob/master/README.md#convenience-methods).

## Super simple to use. Promise.

HTTP as Promised is designed to be the simplest way possible to make http calls. It supports HTTPS and follows redirects by default.

```javascript
var $http = require('http-as-promised');

$http('https://www.github.com')
  .spread(function (response, body){
    console.log(body) // HTTP request was successful
  })
  .catch(function (error){
    console.error(error) // HTTP request was unsuccessful
  });
```

## Options

In addition to [all of the options](https://www.npmjs.org/package/request#request-options-callback-) that the [request module][request] accepts, there are two options specific to HTTP as Promised:

* **`error`** - If set to `false` HTTP as Promised will no longer reject the response with an [`HTTPError`](#http-errors) based on the its HTTP status code. Defaults to `true`. [See below](#http-errors).

* **`resolve`** - Indicates the fulfillment value with which you want the HTTP promise to be resolved. Accepts a string or array of strings. Possible values: 

  * **`['response', 'body']`** *(default)* - By default HTTP as Promised will resolve promises with an array containing the `response` ([`http.IncomingMessage`](http://nodejs.org/api/http.html#http_http_incomingmessage) object) followed by the response `body` (`String`, `Buffer`, or JSON object if the `json` option is supplied). This means that for simple access to the `body` you would probably want to use [`.spread()`](https://github.com/petkaantonov/bluebird/blob/master/API.md#spreadfunction-fulfilledhandler--function-rejectedhandler----promise) instead of [`.then()`](https://github.com/petkaantonov/bluebird/blob/master/API.md#thenfunction-fulfilledhandler--function-rejectedhandler----promise) as seen in the example above.
  * **`['body', 'response']`** - This swaps the ordering of the resolved array so that the "body" comes before the "response" object in the resolved array.
  * **`'response'`** - This will resolve the promise with just the `response` object
  * **`'body'`** - This is probably the one that is going to be the most useful setting for developers looking for a simple interface. Using this means you can easily pass the promises around and know that the fulfillment value is just going to be the `body` object.
 
    ```javascript
    var url = 'https://www.npm.org',
        nock = require('nock')(url);
        
    nock.post('/').reply(200, 'Hello World!');
    $http.post(url, { resolve: 'body' }).then(console.log);
    ```
     
    ```
    "Hello World"
    ```

## HTTP Errors

HTTP as Promised exposes a custom `HTTPError` constructor which is extended from the global `Error` constructor. The `HTTPError` constructor also exposes more specific types of `HTTPError` constructors both for ranges/types of HTTP Errors (4xx/client and 5xx/server) as well as status-code-specific HTTP errors (404, 418, 509, etc.). When instanciated, each of these constructors will be a fully-fledged `instanceof Error` with stack traces and everything. In addition to the `message` and `name` properties, instances of `HTTPError` will also include additional HTTP specific information:

```javascript
var $http = require('http-as-promised'),
    err =  new $http.error[505];

console.log('Error:            ', err instanceof Error);
console.log('HTTP Error:       ', err instanceof $http.error);
console.log('HTTP 5xx Error:   ', err instanceof $http.error['5xx']);
console.log('HTTP Server Error:', err instanceof $http.error['server']);
throw err;
```

```
Error:             true
HTTP Error:        true
HTTP 5xx Error:    true
HTTP Server Error: true
HTTPError: 505 HTTP Version Not Supported
    at Object.<anonymous> (/test.js:2:7)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)
    at startup (node.js:119:16)
    at node.js:906:3
{ [HTTPError: 505 HTTP Version Not Supported]
  statusCode: 505,
  title: 'HTTP Version Not Supported',
  summary: 'server does not support the HTTP protocol version',
  range: '5xx',
  type: 'ServerError',
  message: '505 HTTP Version Not Supported' }
```

When an `HTTPError` is the reason why a response was rejected by HTTP as Promised, it will include some additional properties:

```javascript
var $http = require('http-as-promised'),
    url = 'https://www.npm.org',
    nock = require('nock')(url);

nock.get('/bogus/url').reply(404, 'Cannot find /bogus/url');
$http(url+'/bogus/url').catch(console.log);
```

```
{ [HTTPError: 404 Not Found]
  statusCode: 404,
  title: 'Not Found',
  summary: 'requested resource could not be found',
  range: '4xx',
  type: 'ClientError',
  message: '404 Not Found',
  body: 'Cannot find /bogus/url',
  response: [Object: IncomingMessage]
  options:
   { error: true,
     method: 'GET',
     uri: 'https://www.npm.org/bogus/url' } }
```

## Catching HTTP Errors

Since we're using Bluebird to construct our promises, handling specific HTTP Errors is a breeze using [`.catch()`](https://github.com/petkaantonov/bluebird/blob/master/API.md#catchfunction-errorclassfunction-predicate-function-handler---promise):

```javascript
var $http = require('http-as-promised'),
    url = 'https://stackoverflow.com',
    nock = require('nock')(url);

nock.get('/teapot').reply(418);
$http(url+'/teapot')
  .catch($http.error[418], function (e){
    // Catch 418 I'm A Teapot HTTP Errors
  })
  .catch($http.error.client, function (e){
    // Catch any remaining Client HTTP Errors
  })
  .catch($http.error['4xx'], function (e){
    // An alias for $http.error.client
  })
  .catch($http.error, function (e){
    // Catch any other HTTP Errors that weren't already caught
  })
  .catch(function (e){
    // Catch any other type of Error
  })
```

For better stack traces you can enable bluebird's [`longStackTraces`](https://github.com/petkaantonov/bluebird/blob/master/API.md#promiselongstacktraces---void), as well as bluebird's other [error management configuration](https://github.com/petkaantonov/bluebird/blob/master/API.md#error-management-configuration) methods by calling them on HTTP as Promised:

```javascript
$http.longStackTraces();
nock.get('/').reply(420);
denialOfService(url).catch(err);

function denialOfService(url){
  return $http(url);
}
```

```
HTTPError: 420 Enhance Your Calm
    at Request.HTTP_RESPONSE [as _callback] (http.promise.js:73:25)
    at Request.self.callback (node_modules/request/request.js:237:22)
    at Request.EventEmitter.emit (events.js:98:17)
    at Request.<anonymous> (node_modules/request/request.js:1146:14)
    at Request.EventEmitter.emit (events.js:117:20)
    at OutgoingMessage.<anonymous> (node_modules/request/request.js:1097:12)
    at OutgoingMessage.EventEmitter.emit (events.js:117:20)
    at node_modules/nock/lib/request_overrider.js:419:18
    at Object._onImmediate (node_modules/nock/lib/request_overrider.js:438:9)
From previous event:
    at new Promise (node_modules/bluebird/js/main/promise.js:82:37)
    at HTTP (http.promise.js:56:12)
    at denialOfService (test.js:12:10)
    at Object.<anonymous> (test.js:9:1)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
 { [HTTPError: 420 Enhance Your Calm]
   statusCode: 420,
   title: 'Enhance Your Calm',
   summary: 'Twitter rate limiting',
   range: '4xx',
   type: 'ClientError',
   message: '420 Enhance Your Calm',
   body: '',
   options: { error: true, method: 'GET', uri: 'https://twitter.com' } }
```

## For those times you really just need request

You can directly access the request module used by the HTTP as Promised module:

```javascript
var $http = require('http-as-promised');
$http.request('http://google.com/doodle.png').pipe(fs.createWriteStream('doodle.png'))
```

[npm-image]: https://img.shields.io/npm/v/http-as-promised.svg?style=flat-square
[npm-url]: https://npmjs.org/package/http-as-promised
[travis-image]: http://img.shields.io/travis/jcready/http-as-promised.svg?style=flat-square
[travis-url]: https://travis-ci.org/jcready/http-as-promised
[coveralls-image]: http://img.shields.io/coveralls/jcready/http-as-promised.svg?style=flat-square
[coveralls-url]: https://coveralls.io/r/jcready/http-as-promised?branch=master
[dependencies-image]: https://img.shields.io/david/jcready/http-as-promised.svg?style=flat-square
[dependencies-url]: https://david-dm.org/jcready/http-as-promised
[codeclimate-image]: https://img.shields.io/codeclimate/github/jcready/http-as-promised.svg?style=flat-square
[codeclimate-url]: https://codeclimate.com/github/jcready/http-as-promised

[bluebird]: https://www.npmjs.org/package/bluebird
[request]: https://www.npmjs.org/package/request
[create-error]: https://www.npmjs.org/package/create-error;

---
_Source: https://npm.io/package/http-as-promised · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
