Sunday, January 17, 2021

Node.js exec with promisify

I'm working on a project where Nodejs is used for the backend and redis is used for caching application data.  Here's an example of making a shell command to delete redis cache keys using child_process exec and promisify.  I find it easier (and more intuitive) to use async/await than to use callbacks.

CentOS Linux release 7.3.1611 (Core)
node v14.9.0

// child process currently doesn't natively support promises, however can wrap the
// methods with promises using built-in promisify util
const { promisify } = require("util");
const execAsync = promisify(require("child_process").exec);

 * Deletes all keys from cache that start with cacheCode param.  If
 * cacheCode is not defined, deletes all cache.
 * @param {String} cacheCode.
 * @throws {Error}
 * @returns {String} how many keys effected
async function flushFromCache(cacheCode) {
  const pattern = cacheCode ? ` --pattern ${cacheCode}_*` : "";
  const command = `redis-cli --scan${pattern} | xargs redis-cli del`;
  try {
    const execResult = await execAsync(command);
    // result looks like { stdout: string, stderr: string }.
    // stdout is populated when everything goes nicely.
    // stderr is populated if error occurred while running command
    if (execResult.stderr) {
      throw new Error(execResult.stderr);

    // When there are keys deleted the result looks like:
    // (integer) 2
    // When there are no keys found the result looks like:
    // ERR wrong number of arguments for 'del' command
    let result;
    if (execResult.stdout.includes("ERR")) {
      result = `No ${cacheCode ? `'${cacheCode}'` : ""} keys to flush`;
    } else {
      result = `${execResult.stdout.trim()} ${
        cacheCode ? `'${cacheCode}'` : ""
      } keys flushed`;
    return result;
  } catch (e) {
    // this error can occur if the command is bad
    throw new Error(e.message);

module.exports = {

These articles were helpful:

No comments:

Post a Comment

I appreciate your time in leaving a comment!