explicitly report errors in MainThreadFlipperReceiver

Summary: Use responder rather than allowing exception to propagate.

Reviewed By: jknoxville

Differential Revision: D14538883

fbshipit-source-id: 2774a2adfcee356e1853fa3bf3c01aa113181262
This commit is contained in:
Vlad Albulescu
2019-03-27 08:02:15 -07:00
committed by Facebook Github Bot
parent b2d1506f15
commit de46240272
2 changed files with 72 additions and 6 deletions

View File

@@ -9,32 +9,47 @@ package com.facebook.flipper.plugins.common;
import android.os.Handler;
import android.os.Looper;
import com.facebook.flipper.core.ErrorReportingRunnable;
import com.facebook.flipper.core.FlipperConnection;
import com.facebook.flipper.core.FlipperObject;
import com.facebook.flipper.core.FlipperReceiver;
import com.facebook.flipper.core.FlipperResponder;
import java.io.PrintWriter;
import java.io.StringWriter;
public abstract class MainThreadFlipperReceiver implements FlipperReceiver {
public MainThreadFlipperReceiver(FlipperConnection connection) {
this.mConnection = connection;
// TODO(T41065412): remove unused constructor argument.
}
private final FlipperConnection mConnection;
private final Handler mHandler = new Handler(Looper.getMainLooper());
@Override
public final void onReceive(final FlipperObject params, final FlipperResponder responder) {
mHandler.post(
new ErrorReportingRunnable(mConnection) {
new Runnable() {
@Override
public void runOrThrow() throws Exception {
onReceiveOnMainThread(params, responder);
public void run() {
try {
onReceiveOnMainThread(params, responder);
} catch (Exception ex) {
responder.error(
new FlipperObject.Builder()
.put("name", ex.getClass().getCanonicalName())
.put("message", ex.getMessage())
.put("stacktrace", getStackTraceString(ex))
.build());
}
}
});
}
private static String getStackTraceString(Throwable th) {
StringWriter stringWriter = new StringWriter();
th.printStackTrace(new PrintWriter(stringWriter));
return stringWriter.toString();
}
public abstract void onReceiveOnMainThread(FlipperObject params, FlipperResponder responder)
throws Exception;
}

View File

@@ -0,0 +1,51 @@
/*
* Copyright (c) 2018-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the LICENSE
* file in the root directory of this source tree.
*
*/
package com.facebook.flipper.plugins.common;
import com.facebook.flipper.core.FlipperObject;
import com.facebook.flipper.core.FlipperResponder;
import com.facebook.flipper.testing.FlipperConnectionMock;
import com.facebook.flipper.testing.FlipperResponderMock;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
@RunWith(RobolectricTestRunner.class)
public class MainThreadFlipperReceiverTest {
FlipperConnectionMock connection;
FlipperResponderMock responder;
@Before
public void setup() throws Exception {
connection = new FlipperConnectionMock();
responder = new FlipperResponderMock();
}
@Test
public void errorIsPassedToResponder() throws Exception {
MainThreadFlipperReceiver receiver =
new MainThreadFlipperReceiver(connection) {
public void onReceiveOnMainThread(FlipperObject params, FlipperResponder responder)
throws Exception {
throw new RuntimeException("hello exception");
}
};
receiver.onReceive(new FlipperObject.Builder().build(), responder);
Assert.assertEquals(1, responder.errors.size());
FlipperObject error = responder.errors.get(0);
Assert.assertEquals("hello exception", error.getString("message"));
Assert.assertEquals("java.lang.RuntimeException", error.getString("name"));
Assert.assertTrue(
error.getString("stacktrace").contains(MainThreadFlipperReceiver.class.getCanonicalName()));
}
}