Bug 1210658 - Protect Telemetry ping assembly from exceptions in data gathering functions. r=dexter
authorGeorg Fritzsche <georg.fritzsche@googlemail.com>
Mon, 19 Oct 2015 18:23:57 +0200
changeset 268296 28a844f6cd11a1023f8bb062f52ed81d4b4d6d87
parent 268295 958f04b7804fa587506b35b30ec616f986b637ca
child 268297 9a1f6c87afc860defd4da1f5ea249bf492a9d5ff
push id15754
push usergeorg.fritzsche@googlemail.com
push dateMon, 19 Oct 2015 16:24:11 +0000
treeherderfx-team@9a1f6c87afc8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdexter
bugs1210658
milestone44.0a1
Bug 1210658 - Protect Telemetry ping assembly from exceptions in data gathering functions. r=dexter
toolkit/components/telemetry/TelemetrySession.jsm
--- a/toolkit/components/telemetry/TelemetrySession.jsm
+++ b/toolkit/components/telemetry/TelemetrySession.jsm
@@ -1232,62 +1232,74 @@ var Impl = {
    * respectively.
    */
   assemblePayloadWithMeasurements: function(simpleMeasurements, info, reason, clearSubsession) {
     const isSubsession = IS_UNIFIED_TELEMETRY && !this._isClassicReason(reason);
     clearSubsession = IS_UNIFIED_TELEMETRY && clearSubsession;
     this._log.trace("assemblePayloadWithMeasurements - reason: " + reason +
                     ", submitting subsession data: " + isSubsession);
 
+    // This allows wrapping data retrieval calls in a try-catch block so that
+    // failures don't break the rest of the ping assembly.
+    const protect = (fn) => {
+      try {
+        return fn();
+      } catch (ex) {
+        this.log.error("assemblePayloadWithMeasurements - caught exception", ex);
+        return null;
+      }
+    };
+
     // Payload common to chrome and content processes.
     let payloadObj = {
       ver: PAYLOAD_VERSION,
       simpleMeasurements: simpleMeasurements,
-      histograms: this.getHistograms(isSubsession, clearSubsession),
-      keyedHistograms: this.getKeyedHistograms(isSubsession, clearSubsession),
+      histograms: protect(() => this.getHistograms(isSubsession, clearSubsession)),
+      keyedHistograms: protect(() => this.getKeyedHistograms(isSubsession, clearSubsession)),
     };
 
     // Add extended set measurements common to chrome & content processes
     if (Telemetry.canRecordExtended) {
-      payloadObj.chromeHangs = Telemetry.chromeHangs;
-      payloadObj.threadHangStats = this.getThreadHangStats(Telemetry.threadHangStats);
-      payloadObj.log = TelemetryLog.entries();
+      payloadObj.chromeHangs = protect(() => Telemetry.chromeHangs);
+      payloadObj.threadHangStats = protect(() => this.getThreadHangStats(Telemetry.threadHangStats));
+      payloadObj.log = protect(() => TelemetryLog.entries());
     }
 
     if (Utils.isContentProcess) {
       return payloadObj;
     }
 
     // Additional payload for chrome process.
     payloadObj.info = info;
 
     // Add extended set measurements for chrome process.
     if (Telemetry.canRecordExtended) {
-      payloadObj.slowSQL = Telemetry.slowSQL;
-      payloadObj.fileIOReports = Telemetry.fileIOReports;
-      payloadObj.lateWrites = Telemetry.lateWrites;
+      payloadObj.slowSQL = protect(() => Telemetry.slowSQL);
+      payloadObj.fileIOReports = protect(() => Telemetry.fileIOReports);
+      payloadObj.lateWrites = protect(() => Telemetry.lateWrites);
 
       // Add the addon histograms if they are present
-      let addonHistograms = this.getAddonHistograms();
-      if (Object.keys(addonHistograms).length > 0) {
+      let addonHistograms = protect(() => this.getAddonHistograms());
+      if (addonHistograms && Object.keys(addonHistograms).length > 0) {
         payloadObj.addonHistograms = addonHistograms;
       }
 
-      payloadObj.addonDetails = AddonManagerPrivate.getTelemetryDetails();
-      payloadObj.UIMeasurements = UITelemetry.getUIMeasurements();
+      payloadObj.addonDetails = protect(() => AddonManagerPrivate.getTelemetryDetails());
+      payloadObj.UIMeasurements = protect(() => UITelemetry.getUIMeasurements());
 
-      if (Object.keys(this._slowSQLStartup).length != 0 &&
+      if (this._slowSQLStartup &&
+          Object.keys(this._slowSQLStartup).length != 0 &&
           (Object.keys(this._slowSQLStartup.mainThread).length ||
            Object.keys(this._slowSQLStartup.otherThreads).length)) {
         payloadObj.slowSQLStartup = this._slowSQLStartup;
       }
     }
 
     if (this._childTelemetry.length) {
-      payloadObj.childPayloads = this.getChildPayloads();
+      payloadObj.childPayloads = protect(() => this.getChildPayloads());
     }
 
     return payloadObj;
   },
 
   /**
    * Start a new subsession.
    */