Cómo implementar adecuadamente el manejo de errores en caso asíncrono / en espera

Utilizo async / await ecma6 standard sin ninguna biblioteca personalizada.

No entiendo por el momento cómo puedo atrapar y lanzar errores correctamente. Tengo varias funciones asíncronas / en espera y si ocurre un error crítico en algún lugar debajo, quiero arrojar el error a la parte superior y de todas las funciones asíncronas y detener la ejecución de la función.

Traté de arrojar excepciones de la función async / wait y atraparlo en la función de destino, pero recibo un error en node.js:

    this.basicAuthLogin= async function(user)
{
    "use strict";
    const login = new Login(this.host, this.url, user, user.pw);

    //getSessionID throws error
    this.sessionID = getSessionID(result.request.response);
}

(nodo: 13964) UnhandledPromiseRejectionWarning: Rechazo de promesa no controlado (id. de rechazo: 1): Error: la respuesta getSessionID no está definida (nodo: 13964) [DEP0018] DeprecationWarning: Los rechazos de promesa no manejados están en desuso. En el futuro, los rechazos de promesas que no se manejan terminarán el proceso de Node.js con un código de salida distinto de cero. Depurador adjunto.

Entonces, ¿parece que no se me permite lanzar excepciones de las funciones asincrónicas o incluso volver a lanzarlas en el bloque catch de la promesa en node.js?

Entonces, ¿cómo hago para que esto funcione? ¿Se supone que debo detectar el error en la función asincrónica y devolver el error en la promesa y volver a arrojarlo fuera de la función asincrónica?

   this.basicAuthLogin= async function(user)
{
    "use strict";
    const login = new Login(this.host, this.url, user, user.pw);
   try{
    //getSessionID throws error
    this.sessionID = getSessionID(result.request.response);
   } catch(err) { return err;}
}

Pero esto significaría que en mi pila de llamadas desde la primera función asíncrona, cada función debe ser asíncrona y tengo que esperar la promesa a pesar de que realmente no la necesito.

Espero que alguien pueda iluminarme.

Saludos Ruvi

Edite el pseudocódigo básico de la pila de llamadas:

   async startTest[arr]{

    for (var i = 0; i < arr.length; i++)
    {
      try {
          await runStep(arr[i];
        } catch(err) { 
            console.log(err);
            break; 
        }
      }
    }

  async runStep(step)
  {
     try {
     var userIsValid = await validateUser(step.user);
     var req = buildRequest(step.request);
     var result = await sendRequest(req);
     var verify = verifyResult();
     } catch(err){ throw err;}
  }

  async validateUser(user)
  {
     //make checks
     //
     var result = await this.authenticate(parameter).catch(err => {throw err});
     userFound = true;
   }

  function authenticate(parameter) {
  //can throw async function
   basicAuthLogin(parameter).catch(err => {throw err};

   }

  function async basicAuthLogin(parameter()
  {
   try {
    //can throw  async function
      var result = await request(parameter);
      //can throw sync function
      this.sessionID = getSessionID(response);
      //can throw   sync function
      } catch(err) { throw err; }
   }

Respuestas a la pregunta(1)

Su respuesta a la pregunta