private onMessageReceived()

in src/windowPostMessageProxy.ts [219:330]


  private onMessageReceived(event: MessageEvent) {
    if (this.logMessages) {
      console.log(`${this.name} Received message:`);
      console.log(`type: ${event.type}`);
      console.log(JSON.stringify(event.data, null, '  '));
    }

    let sendingWindow = this.eventSourceOverrideWindow || event.source;
    let message: any = event.data;

    if (typeof message !== "object") {
      if (!this.suppressWarnings) {
        console.warn(`Proxy(${this.name}): Received message that was not an object. Discarding message`);
      }
      return;
    }

    let trackingProperties: ITrackingProperties;
    try {
      trackingProperties = this.getTrackingProperties(message);
    }
    catch (e) {
      if (!this.suppressWarnings) {
        console.warn(`Proxy(${this.name}): Error occurred when attempting to get tracking properties from incoming message:`, JSON.stringify(message, null, '  '), "Error: ", e);
      }
    }

    let deferred: IDeferred;
    if (trackingProperties) {
      deferred = this.pendingRequestPromises[trackingProperties.id];
    }

    // If message does not have a known ID, treat it as a request
    // Otherwise, treat message as response
    if (!deferred) {
      const handled = this.handlers.some(handler => {
        let canMessageBeHandled = false;
        try {
          canMessageBeHandled = handler.test(message);
        }
        catch (e) {
          if (!this.suppressWarnings) {
            console.warn(`Proxy(${this.name}): Error occurred when handler was testing incoming message:`, JSON.stringify(message, null, '  '), "Error: ", e);
          }
        }

        if (canMessageBeHandled) {
          let responseMessagePromise: Promise<any>;

          try {
            responseMessagePromise = Promise.resolve(handler.handle(message));
          }
          catch (e) {
            if (!this.suppressWarnings) {
              console.warn(`Proxy(${this.name}): Error occurred when handler was processing incoming message:`, JSON.stringify(message, null, '  '), "Error: ", e);
            }
            responseMessagePromise = Promise.resolve();
          }

          responseMessagePromise
            .then(responseMessage => {
              if (!responseMessage) {
                const warningMessage = `Handler for message: ${JSON.stringify(message, null, '  ')} did not return a response message. The default response message will be returned instead.`;
                if (!this.suppressWarnings) {
                  console.warn(`Proxy(${this.name}): ${warningMessage}`);
                }
                responseMessage = {
                  warning: warningMessage
                };
              }
              this.sendResponse(sendingWindow, responseMessage, trackingProperties);
            });

          return true;
        }
      });

      /**
       * TODO: Consider returning an error message if nothing handled the message.
       * In the case of the Report receiving messages all of them should be handled,
       * however, in the case of the SDK receiving messages it's likely it won't register handlers
       * for all events. Perhaps make this an option at construction time.
       */
      if (!handled && !this.suppressWarnings) {
        console.warn(`Proxy(${this.name}) did not handle message. Handlers: ${this.handlers.length}  Message: ${JSON.stringify(message, null, '')}.`);
        // this.sendResponse({ notHandled: true }, trackingProperties);
      }
    }
    else {
      /**
       * If error message reject promise,
       * Otherwise, resolve promise
       */
      let isErrorMessage = true;
      try {
        isErrorMessage = this.isErrorMessage(message);
      }
      catch (e) {
        console.warn(`Proxy(${this.name}) Error occurred when trying to determine if message is consider an error response. Message: `, JSON.stringify(message, null, ''), 'Error: ', e);
      }

      if (isErrorMessage) {
        deferred.reject(message);
      }
      else {
        deferred.resolve(message);
      }

      // TODO: Move to .finally clause up where promise is created for better maitenance like original proxy code.
      delete this.pendingRequestPromises[trackingProperties.id];
    }
  }