From db07768133a26df00e0025fb68f327689a7c0cc9 Mon Sep 17 00:00:00 2001 From: Tim Lancina Date: Wed, 27 Apr 2016 13:00:57 -0500 Subject: [PATCH] fix(plugin): handle rejection when Cordova is undefined Zone.js now (helpfully) throws an error on unhandled rejections in promises. This is great because they no longer silently fail, but we were relying on that behavior for the case where the plugin isn't installed or Cordova isn't available. With this change, those cases won't throw an unhandled rejection error, but all regular plugin errors still should. --- src/plugins/plugin.ts | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/src/plugins/plugin.ts b/src/plugins/plugin.ts index a06bb16d67..faa4a9728b 100644 --- a/src/plugins/plugin.ts +++ b/src/plugins/plugin.ts @@ -81,17 +81,15 @@ function callCordovaPlugin(pluginObj:any, methodName:string, args:any[], opts:an // Do this check in here in the case that the Web API for this plugin is available (for example, Geolocation). if(!window.cordova) { cordovaWarn(pluginObj.name, methodName); - reject && reject({ + return { error: 'cordova_not_available' - }); - return; + } } pluginWarn(pluginObj, methodName); - reject && reject({ + return { error: 'plugin_not_installed' - }); - return; + }; } // console.log('Cordova calling', pluginObj.name, methodName, args); @@ -118,14 +116,27 @@ function getPromise(cb) { } function wrapPromise(pluginObj:any, methodName:string, args:any[], opts:any={}) { - return getPromise((resolve, reject) => { - callCordovaPlugin(pluginObj, methodName, args, opts, resolve, reject); - }) + let pluginResult, rej; + const p = getPromise((resolve, reject) => { + pluginResult = callCordovaPlugin(pluginObj, methodName, args, opts, resolve, reject); + rej = reject; + }); + // Angular throws an error on unhandled rejection, but in this case we have already printed + // a warning that Cordova is undefined or the plugin is uninstalled, so there is no reason + // to error + if (pluginResult && pluginResult.error) { + p.catch(() => {}); + rej(pluginResult.error); + } + return p; } function wrapObservable(pluginObj:any, methodName:string, args:any[], opts:any = {}) { return new Observable(observer => { let pluginResult = callCordovaPlugin(pluginObj, methodName, args, opts, observer.next.bind(observer), observer.error.bind(observer)); + if (pluginResult && pluginResult.error) { + observer.error(pluginResult.error); + } return () => { try {