Skip to content

Commit 531c3cb

Browse files
committed
catch all Throwables from SerialInputOutputManager.Listener methods (#601)
to avoid breaking Interface changes, Error from onNewData() is wrapped into Exception when calling onRunError()
1 parent f538097 commit 531c3cb

File tree

4 files changed

+70
-3
lines changed

4 files changed

+70
-3
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ If using gradle kotlin use line
4545
Add library to dependencies
4646
```gradle
4747
dependencies {
48-
implementation 'com.github.mik3y:usb-serial-for-android:3.8.0'
48+
implementation 'com.github.mik3y:usb-serial-for-android:3.8.1'
4949
}
5050
```
5151

usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/util/SerialInputOutputManager.java

+10-2
Original file line numberDiff line numberDiff line change
@@ -203,15 +203,23 @@ public void run() {
203203
}
204204
step();
205205
}
206-
} catch (Exception e) {
206+
} catch (Throwable e) {
207207
if(mSerialPort.isOpen()) {
208208
Log.w(TAG, "Run ending due to exception: " + e.getMessage(), e);
209209
} else {
210210
Log.i(TAG, "Socket closed");
211211
}
212212
final Listener listener = getListener();
213213
if (listener != null) {
214-
listener.onRunError(e);
214+
try {
215+
if (e instanceof Exception) {
216+
listener.onRunError((Exception) e);
217+
} else {
218+
listener.onRunError(new Exception(e));
219+
}
220+
} catch (Throwable t) {
221+
Log.w(TAG, "Exception in onRunError: " + t.getMessage(), t);
222+
}
215223
}
216224
} finally {
217225
synchronized (this) {

usbSerialForAndroid/src/test/java/android/util/Log.java

+5
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ public static int w(String tag, String msg) {
1717
return 0;
1818
}
1919

20+
public static int w(String tag, String msg, Throwable tr) {
21+
System.out.println("WARN: " + tag + ": " + msg + " / " + tr.getMessage());
22+
return 0;
23+
}
24+
2025
public static int e(String tag, String msg) {
2126
System.out.println("ERROR: " + tag + ": " + msg);
2227
return 0;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package com.hoho.android.usbserial.util;
2+
3+
import static org.junit.Assert.assertEquals;
4+
import static org.mockito.Mockito.mock;
5+
import static org.mockito.Mockito.when;
6+
7+
import android.hardware.usb.UsbEndpoint;
8+
import android.os.Process;
9+
10+
import com.hoho.android.usbserial.driver.CommonUsbSerialPort;
11+
12+
import org.junit.Test;
13+
14+
public class SerialInputOutputManagerTest {
15+
16+
17+
// catch all Throwables in noNewData() and onRunError()
18+
@Test
19+
public void throwable() throws Exception {
20+
21+
class ExceptionListener implements SerialInputOutputManager.Listener {
22+
public Exception e;
23+
@Override public void onNewData(byte[] data) { throw new RuntimeException("exception1"); }
24+
@Override public void onRunError(Exception e) { this.e = e; throw new RuntimeException("exception2"); }
25+
}
26+
class ErrorListener implements SerialInputOutputManager.Listener {
27+
public Exception e;
28+
@Override public void onNewData(byte[] data) { throw new UnknownError("error1"); }
29+
@Override public void onRunError(Exception e) { this.e = e; throw new UnknownError("error2");}
30+
}
31+
32+
UsbEndpoint readEndpoint = mock(UsbEndpoint.class);
33+
when(readEndpoint.getMaxPacketSize()).thenReturn(16);
34+
CommonUsbSerialPort port = mock(CommonUsbSerialPort.class);
35+
when(port.getReadEndpoint()).thenReturn(readEndpoint);
36+
when(port.read(new byte[16], 0)).thenReturn(1);
37+
SerialInputOutputManager manager = new SerialInputOutputManager(port);
38+
manager.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
39+
40+
ExceptionListener exceptionListener = new ExceptionListener();
41+
manager.setListener(exceptionListener);
42+
manager.run();
43+
assertEquals(RuntimeException.class, exceptionListener.e.getClass());
44+
assertEquals("exception1", exceptionListener.e.getMessage());
45+
46+
ErrorListener errorListener = new ErrorListener();
47+
manager.setListener(errorListener);
48+
manager.run();
49+
assertEquals(Exception.class, errorListener.e.getClass());
50+
assertEquals("java.lang.UnknownError: error1", errorListener.e.getMessage());
51+
assertEquals(UnknownError.class, errorListener.e.getCause().getClass());
52+
assertEquals("error1", errorListener.e.getCause().getMessage());
53+
}
54+
}

0 commit comments

Comments
 (0)