Made flipper plugins a little more robust
Summary: Added some assertions and string casts to make plugins a bit more robust Reviewed By: passy Differential Revision: D19427909 fbshipit-source-id: 46a3138805db865b538f745fae25ce1897e35736
This commit is contained in:
committed by
Facebook Github Bot
parent
db9c41303d
commit
28fd95589f
@@ -72,10 +72,14 @@ public class FlipperReactNativeJavaScriptPluginManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void send(String pluginId, String method, String data) {
|
public void send(String pluginId, String method, String data) {
|
||||||
|
FlipperReactNativeJavaScriptPlugin plugin = getPlugin(pluginId);
|
||||||
|
if (data == null) {
|
||||||
|
plugin.getConnection().send(method, (FlipperObject) null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
// Optimization: throwing raw strings around to the desktop would probably avoid some double
|
// Optimization: throwing raw strings around to the desktop would probably avoid some double
|
||||||
// parsing...
|
// parsing...
|
||||||
Object parsedData = parseJSON(data);
|
Object parsedData = parseJSON(data);
|
||||||
FlipperReactNativeJavaScriptPlugin plugin = getPlugin(pluginId);
|
|
||||||
if (parsedData instanceof FlipperArray) {
|
if (parsedData instanceof FlipperArray) {
|
||||||
plugin.getConnection().send(method, (FlipperArray) parsedData);
|
plugin.getConnection().send(method, (FlipperArray) parsedData);
|
||||||
} else {
|
} else {
|
||||||
@@ -134,14 +138,17 @@ public class FlipperReactNativeJavaScriptPluginManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static Object /* FlipperArray | FlipperObject */ parseJSON(String json) {
|
private static Object /* FlipperArray | FlipperObject */ parseJSON(String json) {
|
||||||
|
if (json == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
// returns either a FlipperObject or Flipper array, pending the data
|
// returns either a FlipperObject or Flipper array, pending the data
|
||||||
try {
|
try {
|
||||||
JSONTokener tokener = new JSONTokener(json);
|
JSONTokener tokener = new JSONTokener(json);
|
||||||
if (tokener.nextClean() == '[') {
|
char firstChar = tokener.nextClean();
|
||||||
tokener.back();
|
tokener.back();
|
||||||
|
if (firstChar == '[') {
|
||||||
return new FlipperArray(new JSONArray(tokener));
|
return new FlipperArray(new JSONArray(tokener));
|
||||||
} else {
|
} else {
|
||||||
tokener.back();
|
|
||||||
return new FlipperObject(new JSONObject(tokener));
|
return new FlipperObject(new JSONObject(tokener));
|
||||||
}
|
}
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
|
|||||||
@@ -32,12 +32,14 @@ public class FlipperReactNativeJavaScriptReceiver implements FlipperReceiver {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(FlipperObject params, FlipperResponder responder) throws Exception {
|
public void onReceive(FlipperObject params, FlipperResponder responder) throws Exception {
|
||||||
String responderId = manager.createResponderId(responder);
|
|
||||||
WritableMap eventData = Arguments.createMap();
|
WritableMap eventData = Arguments.createMap();
|
||||||
eventData.putString("plugin", plugin);
|
eventData.putString("plugin", plugin);
|
||||||
eventData.putString("method", method);
|
eventData.putString("method", method);
|
||||||
eventData.putString("params", params.toJsonString());
|
eventData.putString("params", params.toJsonString());
|
||||||
eventData.putString("responderId", responderId);
|
if (responder != null) {
|
||||||
|
String responderId = manager.createResponderId(responder);
|
||||||
|
eventData.putString("responderId", responderId);
|
||||||
|
}
|
||||||
module.sendJSEvent("react-native-flipper-receive-event", eventData);
|
module.sendJSEvent("react-native-flipper-receive-event", eventData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
31
react-native/react-native-flipper/index.js
vendored
31
react-native/react-native-flipper/index.js
vendored
@@ -17,6 +17,20 @@ export default Flipper;
|
|||||||
const listeners = {}; // plugin#method -> callback
|
const listeners = {}; // plugin#method -> callback
|
||||||
const plugins = {}; // plugin -> Plugin
|
const plugins = {}; // plugin -> Plugin
|
||||||
|
|
||||||
|
function assertSerializable(data) {
|
||||||
|
if (
|
||||||
|
data === undefined ||
|
||||||
|
Array.isArray(data) ||
|
||||||
|
(data && typeof data === 'object')
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
throw new Error(
|
||||||
|
'Flipper: Expected serializable (undefined, an array or an object). Got: ' +
|
||||||
|
data,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
class Connection {
|
class Connection {
|
||||||
connected;
|
connected;
|
||||||
pluginId;
|
pluginId;
|
||||||
@@ -30,15 +44,20 @@ class Connection {
|
|||||||
if (!this.connected) {
|
if (!this.connected) {
|
||||||
throw new Error('Cannot send data, not connected');
|
throw new Error('Cannot send data, not connected');
|
||||||
}
|
}
|
||||||
|
assertSerializable(data);
|
||||||
Flipper.send(this.pluginId, method, JSON.stringify(data));
|
Flipper.send(this.pluginId, method, JSON.stringify(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
reportErrorWithMetadata(reason, stackTrace) {
|
reportErrorWithMetadata(reason, stackTrace) {
|
||||||
Flipper.reportErrorWithMetadata(this.pluginId, reason, stackTrace);
|
Flipper.reportErrorWithMetadata(
|
||||||
|
this.pluginId,
|
||||||
|
'' + reason,
|
||||||
|
'' + stackTrace,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
reportError(error) {
|
reportError(error) {
|
||||||
Flipper.reportError(this.pluginId, error);
|
Flipper.reportError(this.pluginId, '' + error);
|
||||||
}
|
}
|
||||||
|
|
||||||
receive(method, listener) {
|
receive(method, listener) {
|
||||||
@@ -59,6 +78,7 @@ class Responder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
success(response) {
|
success(response) {
|
||||||
|
assertSerializable(response);
|
||||||
Flipper.respondSuccess(
|
Flipper.respondSuccess(
|
||||||
this.responderId,
|
this.responderId,
|
||||||
response == null ? null : JSON.stringify(response),
|
response == null ? null : JSON.stringify(response),
|
||||||
@@ -66,15 +86,13 @@ class Responder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
error(response) {
|
error(response) {
|
||||||
|
assertSerializable(response);
|
||||||
Flipper.respondError(this.responderId, JSON.stringify(response));
|
Flipper.respondError(this.responderId, JSON.stringify(response));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function startEventListeners() {
|
function startEventListeners() {
|
||||||
const emitter = new NativeEventEmitter(Flipper);
|
const emitter = new NativeEventEmitter(Flipper);
|
||||||
emitter.removeAllListeners('react-native-flipper-plugin-connect');
|
|
||||||
emitter.removeAllListeners('react-native-flipper-plugin-disconnect');
|
|
||||||
emitter.removeAllListeners('react-native-flipper-receive-event');
|
|
||||||
|
|
||||||
emitter.addListener('react-native-flipper-plugin-connect', event => {
|
emitter.addListener('react-native-flipper-plugin-connect', event => {
|
||||||
const {plugin} = event;
|
const {plugin} = event;
|
||||||
@@ -98,7 +116,8 @@ function startEventListeners() {
|
|||||||
const {plugin, method, params, responderId} = event;
|
const {plugin, method, params, responderId} = event;
|
||||||
const key = plugin + '#' + method;
|
const key = plugin + '#' + method;
|
||||||
if (listeners[key]) {
|
if (listeners[key]) {
|
||||||
const responder = new Responder(responderId);
|
const responder =
|
||||||
|
responderId != null ? new Responder(responderId) : undefined;
|
||||||
listeners[key](JSON.parse(params), responder);
|
listeners[key](JSON.parse(params), responder);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user