Home > Net >  Why Unexpected reserved word 'await' even when my function is declared as async?
Why Unexpected reserved word 'await' even when my function is declared as async?

Time:05-28

I'm putting together some Node.js code for querying LDAP that uses promises. When I run it, I get Unexpected reserved word concerning the await on line 43. This part:

let connection = await connect(ldapURL).catch((err) => {
  console.error('LDAP server error:', err);
  reject(err);
});

The entire code is shown below.

I have a promise returned in the connect() function and that's working fine. In fact, if I remove the promise from the listObjects() function, the console.debug(results); line prints exactly what I'm expecting.

So why is the await connect() causing an error in my listObjects() function? My searching has yielded a lot of answers saying, "You need to use async," but I already have my listObjects() declared as async.

Where have I gone wrong?

Full Code:

#!/usr/bin/env node

import ldapjs from 'ldapjs';

const ldapURL = [ 'ldap://127.0.0.1:389' ];
const bindDN = 'uid=search,dc=home';
const bindPassword = 'P@ssw0rd';

function connect(serverURL) {
  return new Promise((resolve, reject) => {
    const client = ldapjs.createClient({
      url: serverURL
    });

    client.on('connect', () => {
      console.debug('Connected to:', ldapURL);
      console.debug('Binding as:', bindDN);
      client.bind(bindDN, bindPassword, (err) => {
        if (err) {
          console.debug(err.message);
          reject('Bind credentials rejected.');
        }
        else {
          resolve(client);
        }
      });
    });

    client.on('error', (err) => {
      reject('Unable to connect to '   serverURL);
    });
  });
}

/**
 * Search LDAP and return objects.
 * @baseDN {string}  Where to start, like 'ou=People,dc=example,dc=com'
 * @filter {string}  Optional LDAP query to limit results, like '(objectClass=posixAccount)'
 * @returns {promise}  ... Eventually.
 */
async function listObjects(baseDN, filter) {
  return new Promise((resolve, reject) => {
    let connection = await connect(ldapURL).catch((err) => {
      console.error('LDAP server error:', err);
      reject(err);
    });

    let opts = {
      filter: filter,
      scope: 'sub'
    };

    let results = [];
    connection.search(`${baseDN}`, opts, (err, res) => {
      res.on('searchEntry', (entry) => {
        results.push(entry);
      });

      res.on('end', () => {
        connection.unbind(() => {
          console.debug(results);
          resolve(results);
        });
      });
    });
  });
}

let ldapObjects = await listObjects('dc=home', '(objectClass=posixAccount)');
console.log(ldapObjects);

CodePudding user response:

After helpful suggestions in the comments, the solution was to Move the line return new Promise((resolve, reject) => { down so that it only wraps the connection.search(…) part as suggested by Bergi

Here is the code after that modification:

#!/usr/bin/env node

import ldapjs from 'ldapjs';

const ldapURL = [ 'ldap://127.0.0.1:389' ];
const bindDN = 'uid=search,dc=home';
const bindPassword = 'P@ssw0rd';

function connect(serverURL) {
  return new Promise((resolve, reject) => {
    const client = ldapjs.createClient({
      url: serverURL
    });

    client.on('connect', () => {
      console.debug('Connected to:', ldapURL);
      console.debug('Binding as:', bindDN);
      client.bind(bindDN, bindPassword, (err) => {
        if (err) {
          console.debug(err.message);
          reject('Bind credentials rejected.');
        }
        else {
          resolve(client);
        }
      });
    });

    client.on('error', (err) => {
      reject('Unable to connect to '   serverURL);
    });
  });
}

/**
 * Search LDAP and return objects.
 * @baseDN {string}  Where to start, like 'ou=People,dc=example,dc=com'
 * @filter {string}  Optional LDAP query to limit results, like '(objectClass=posixAccount)'
 * @returns {promise}  ... Eventually.
 */
async function listObjects(baseDN, filter) {
  let connection = await connect(ldapURL).catch((err) => {
    console.error('LDAP server error:', err);
    reject(err);
  });

  let opts = {
    filter: filter,
    scope: 'sub'
  };

  let results = [];
  return new Promise((resolve, reject) => {
    connection.search(`${baseDN}`, opts, (err, res) => {
      res.on('searchEntry', (entry) => {
        results.push(entry);
      });

      res.on('end', () => {
        connection.unbind(() => {
          resolve(results);
        });
      });
    });
  });
}

let ldapObjects = await listObjects('dc=home', '(objectClass=posixAccount)');
console.log(ldapObjects);

CodePudding user response:

I think you have to remove new Promise because async return the data wraps in the Promise. I think that your ldapObjects store a Promise and listObjects return a Promise wrap inside a Promise.

  • Related