diff --git a/mobile/android/base/EventDispatcher.java b/mobile/android/base/EventDispatcher.java
index 4d284ae067f55..48e06bfa57bd8 100644
--- a/mobile/android/base/EventDispatcher.java
+++ b/mobile/android/base/EventDispatcher.java
@@ -11,6 +11,7 @@
 import org.mozilla.gecko.util.GeckoEventListener;
 import org.mozilla.gecko.util.NativeEventListener;
 import org.mozilla.gecko.util.NativeJSContainer;
+import org.mozilla.gecko.util.NativeJSObject;
 
 import org.json.JSONException;
 import org.json.JSONObject;
@@ -141,7 +142,11 @@ public void unregisterGeckoThreadListener(final GeckoEventListener listener,
 
     public void dispatchEvent(final NativeJSContainer message) {
         // First try native listeners.
-        final String type = message.getString("type");
+        final String type = message.optString("type", null);
+        if (type == null) {
+            Log.e(LOGTAG, "JSON message must have a type property");
+            return;
+        }
 
         final List<NativeEventListener> listeners;
         synchronized (mGeckoThreadNativeListeners) {
@@ -158,8 +163,12 @@ public void dispatchEvent(final NativeJSContainer message) {
             if (listeners.size() == 0) {
                 Log.w(LOGTAG, "No listeners for " + type);
             }
-            for (final NativeEventListener listener : listeners) {
-                listener.handleMessage(type, message, callback);
+            try {
+                for (final NativeEventListener listener : listeners) {
+                    listener.handleMessage(type, message, callback);
+                }
+            } catch (final NativeJSObject.InvalidPropertyException e) {
+                Log.e(LOGTAG, "Exception occurred while handling " + type, e);
             }
             // If we found native listeners, we assume we don't have any JSON listeners
             // and return early. This assumption is checked when registering listeners.
@@ -170,9 +179,9 @@ public void dispatchEvent(final NativeJSContainer message) {
             // If we didn't find native listeners, try JSON listeners.
             dispatchEvent(new JSONObject(message.toString()), callback);
         } catch (final JSONException e) {
-            Log.e(LOGTAG, "Cannot parse JSON");
+            Log.e(LOGTAG, "Cannot parse JSON", e);
         } catch (final UnsupportedOperationException e) {
-            Log.e(LOGTAG, "Cannot convert message to JSON");
+            Log.e(LOGTAG, "Cannot convert message to JSON", e);
         }
     }