Can't send HTTPs requests from the Netlify Build plugin

Howdy folks! :wave:

Iโ€™ve stumbled upon a roadblock when trying to build a Netlify Build plugin.

As a part of that plugin, I need to send HTTP requests. The problem is that I canโ€™t get HTTP requests to run. Iโ€™ve tried different HTTP libraries to no avail.

Hereโ€™s my index.js file:

'use strict';

const https = require('https');

module.exports = {
  name: 'hello-world-plugin',
  onEnd: async () => {
    console.log('Starting the execution');

    const request = https.get({ hostname: 'tryhexadecimal.com' }, (response) => {
      console.log('Sending HTTP request');
      const certificate = response.connection.getPeerCertificate();
      const dateInfo = {
        valid_from: certificate.valid_from,
        valid_to: certificate.valid_to,
        issuer: certificate.issuer.CN,
        fingerprint: certificate.fingerprint,
        serialNumber: certificate.serialNumber
      };
      console.log(response.code);
      console.log(JSON.stringify(dateInfo));
    });

    request.on('error', (e) => {
      console.log(JSON.stringify(e.message));
    })

    request.end();

    console.log('Finita!');
  }
}

Hereโ€™s the build output from the netlify build command. As you can see below, Sending HTTP request message doesnโ€™t appear in the console. Iโ€™ve tried different URLs to see if that request appears in server logs, but there was nothing. Any ideas?

The script itself works, though.

โฏ Starting Netlify Build v0.1.117
  https://github.com/netlify/build
โ€‹
โฏ Flags
  dry: false
โ€‹
โฏ Current directory
  ~/hexadecimal-static
โ€‹
โฏ Config file
  ~/hexadecimal-static/netlify.toml
โ€‹
โฏ Context
  production
โ€‹
โฏ Installing local plugins dependencies
   - ./plugins/netlify-plugin-hello-world
โ€‹
โฏ Loading plugins
   - ./plugins/netlify-plugin-hello-world
โ€‹
โฏ Running Netlify Build Lifecycle
  Found 2 commands. Let's do this!

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ 1. Running build.lifecycle.onBuild command from netlify.toml config file โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ€‹
Running command "bundle exec nanoc compile --env=prod && bundle exec nanoc check mixed_content stale ilinks && bundle exec ruby post_process.rb"
Loading siteโ€ฆ done
~/.rbenv/versions/2.7.0/lib/ruby/gems/2.7.0/gems/nanoc-core-4.11.15/lib/nanoc/core/compiler_loader.rb:35: warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call
~/.rbenv/versions/2.7.0/lib/ruby/gems/2.7.0/gems/nanoc-core-4.11.15/lib/nanoc/core/compiler.rb:8: warning: The called method `initialize' is defined here
Compiling siteโ€ฆ

Site compiled in 0.13s.
Loading siteโ€ฆ done
~/.rbenv/versions/2.7.0/lib/ruby/gems/2.7.0/gems/nanoc-core-4.11.15/lib/nanoc/core/compiler_loader.rb:35: warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call
~/.rbenv/versions/2.7.0/lib/ruby/gems/2.7.0/gems/nanoc-core-4.11.15/lib/nanoc/core/compiler.rb:8: warning: The called method `initialize' is defined here
  Running check mixed_contentโ€ฆ    ok
  Running check staleโ€ฆ            ok
  Running check internal_linksโ€ฆ   ok
โ€‹
 โœ”  build.lifecycle.onBuild completed in 3637ms

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ 2. Running onEnd command from ./plugins/netlify-plugin-hello-world โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ€‹
Starting the execution
Finita!
โ€‹
 โœ”  ./plugins/netlify-plugin-hello-world onEnd completed in 31ms
โ€‹
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚   Netlify Build Complete    โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ€‹
 โœ”  Netlify Build completed in 6105ms
โ€‹
(๏พ‰โ—•ใƒฎโ—•)๏พ‰*:๏ฝฅ๏พŸโœง Have a nice day!

Hi @jmsftv,

Thanks for reaching out!

The onEnd function seems to finish while there are still ongoing async operations. Instead it should wait for the HTTP response before printing Finita.

There are several ways to do it including:

try {
  const response = await new Promise((resolve, reject) => {
    request.on('error', reject)
    request.on('response', resolve)
  })
  console.log('Sending HTTP request');
  const certificate = response.connection.getPeerCertificate();
  // and so on
} catch (error) {
  // See https://github.com/netlify/build#error-reporting
  utils.build.failBuild('HTTP request failed', { error })
}

Or using p-event:

try {
  const response = await pEvent(request, 'response')
  console.log('Sending HTTP request');
  const certificate = response.connection.getPeerCertificate();
  // and so on
} catch (error) {
  // See https://github.com/netlify/build#error-reporting
  utils.build.failBuild('HTTP request failed', { error })
}

But I would personally recommend using a promisified HTTP request library like got. It will reduce the number of lines of code while enforcing many best practices under the hood (such as automatic retries).

On a different note:

Please let me know if this solves your problem!

1 Like

Hello @ehmicky!

I see why it happens now.

Thanks for pointing this out, because thatโ€™s what I actually need. I will come back to this plugin (and post) once postDeploy hook is out.

Cheers! :tada:

2 Likes

Hey @jmstfv,
Wanted to share an exciting update: onEnd and onSuccess now run after the deploy :tada: You can read more about the change here:

2 Likes