npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

http-as-promised

v2.0.1

Published

Promisified HTTP client

Downloads

772

Readme

HTTP as Promised — Promisified HTTP client.

NPM Version Build Status Test Coverage Code Climate Dependencies

Using bluebird and create-error to make 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 as well as all of request's 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.

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 that the request module 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 based on the its HTTP status code. Defaults to true. See below.

  • 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 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() instead of .then() 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.

      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:

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:

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():

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, as well as bluebird's other error management configuration methods by calling them on HTTP as Promised:

$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:

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