async function executeAction(self, action, scope, path, { throwUnknownError = false } = {}) {
    logger.debug(`Executing action ${action.type}`);
    if (!actionsFunc[action.type]) {
      throw new Error(`Action type "${action.type}" does not exist.`);
    }

    // send message to tell UI the action is executed
    if (path !== undefined) {
      self.event.emit(EVENTS.WEBSOCKET.SEND_ALL, {
        type: WEBSOCKET_MESSAGE_TYPES.SCENE.EXECUTING_ACTION,
        payload: { path },
      });
    }
    try {
      // execute action
      await actionsFunc[action.type](self, action, scope, path);
    } catch (e) {
      if (e instanceof AbortScene) {
        throw e;
      } else {
        if (throwUnknownError) {
          throw e;
        }
        logger.warn(e);
      }
    }

    // send message to tell the UI the action has finished being executed
    if (path !== undefined) {
      self.event.emit(EVENTS.WEBSOCKET.SEND_ALL, {
        type: WEBSOCKET_MESSAGE_TYPES.SCENE.FINISHED_EXECUTING_ACTION,
        payload: { path },
      });
    }

    return null;
  }
@description Execute one action.
@param {object} self - Reference to the SceneManager.
@param {object} action - An Action from the db.
@param {object} scope - The scope passed to all actions.
@param {string} path - The path of the action in the scene JSON.
@param {object} [options={}] - Additional options.
@param {boolean} [options.throwUnknownError=false] - Throw an error if an unknown error happens.
@returns {Promise} Resolve if the action was executed with success.
@example
executeAction(this, action, {});