Permalink
Browse files

Guard against missing native module

Reviewed By: martinbigio

Differential Revision: D4579114

fbshipit-source-id: a2e9f634748e1c56eb9867bfb9e3e66e9cdc5e93
  • Loading branch information...
gaearon authored and facebook-github-bot committed Feb 17, 2017
1 parent 3148cc0 commit 118e88393e389ff70e30ada10a69b72dd31d869a
Showing with 49 additions and 2 deletions.
  1. +46 −2 Libraries/AppState/AppState.js
  2. +3 −0 Libraries/Core/Devtools/setupDevtools.js
@@ -11,6 +11,7 @@
*/
'use strict';
const EventEmitter = require('EventEmitter');
const NativeEventEmitter = require('NativeEventEmitter');
const NativeModules = require('NativeModules');
const RCTAppState = NativeModules.AppState;
@@ -25,6 +26,9 @@ const invariant = require('fbjs/lib/invariant');
* AppState is frequently used to determine the intent and proper behavior when
* handling push notifications.
*
* This module depends on the native RCTAppState module. If you don't include it,
* `AppState.isAvailable` will return `false`, and any method calls will throw.
*
* ### App States
*
* - `active` - The app is running in the foreground
@@ -86,6 +90,7 @@ class AppState extends NativeEventEmitter {
_eventHandlers: Object;
currentState: ?string;
isAvailable: boolean = true;
constructor() {
super(RCTAppState);
@@ -173,6 +178,45 @@ class AppState extends NativeEventEmitter {
}
}
AppState = new AppState();
function throwMissingNativeModule() {
invariant(
false,
'Cannot use AppState module when native RCTAppState is not included in the build.\n' +
'Either include it, or check AppState.isAvailable before calling any methods.'
);
}
class MissingNativeAppStateShim extends EventEmitter {
// AppState
isAvailable: boolean = false;
currentState: ?string = null;
addEventListener() {
throwMissingNativeModule();
}
removeEventListener() {
throwMissingNativeModule();
}
// EventEmitter
addListener() {
throwMissingNativeModule();
}
removeAllListeners() {
throwMissingNativeModule();
}
removeSubscription() {
throwMissingNativeModule();
}
}
// Guard against missing native module by throwing on first method call.
// Keep the API the same so Flow doesn't complain.
const appState = RCTAppState
? new AppState()
: new MissingNativeAppStateShim();
module.exports = AppState;
module.exports = appState;
@@ -20,6 +20,9 @@ if (__DEV__) {
connectToDevTools({
isAppActive() {
// Don't steal the DevTools from currently active app.
// Note: if you add any AppState subscriptions to this file,
// you will also need to guard against `AppState.isAvailable`,
// or the code will throw for bundles that don't have it.
return AppState.currentState !== 'background';
},
// Special case: Genymotion is running on a different host.

3 comments on commit 118e883

@ericnakagawa

This comment has been minimized.

Show comment
Hide comment
@ericnakagawa

ericnakagawa Feb 18, 2017

Contributor

Hi @gaearon, I will need to revert this commit to get Master building again and this PR breaks the website build. Please fix the issues that happen when you run build/generate.js from website folder.

Contributor

ericnakagawa replied Feb 18, 2017

Hi @gaearon, I will need to revert this commit to get Master building again and this PR breaks the website build. Please fix the issues that happen when you run build/generate.js from website folder.

@gaearon

This comment has been minimized.

Show comment
Hide comment
@gaearon

gaearon Feb 20, 2017

Member

Thanks for explaining. I don't think reverting it is appropriate because it fixes the product builds. If there is a mistake in a website script, then we should fix the website script instead of reverting a product fix that blocks FB developers.

I'm going to take a look at the website script, but so far I don't see a build folder in website.

Member

gaearon replied Feb 20, 2017

Thanks for explaining. I don't think reverting it is appropriate because it fixes the product builds. If there is a mistake in a website script, then we should fix the website script instead of reverting a product fix that blocks FB developers.

I'm going to take a look at the website script, but so far I don't see a build folder in website.

@gaearon

This comment has been minimized.

Show comment
Hide comment
@gaearon

gaearon Feb 20, 2017

Member

I can reproduce this by running node server/generate.js in the website folder.
Investigating.

Member

gaearon replied Feb 20, 2017

I can reproduce this by running node server/generate.js in the website folder.
Investigating.

Please sign in to comment.