1
0
mirror of https://github.com/mik3y/usb-serial-for-android synced 2025-06-07 16:06:10 +00:00

catch all Throwables from SerialInputOutputManager.Listener methods (#601) (#606)

to avoid breaking Interface changes, Error from onNewData() is wrapped into Exception when calling onRunError()
This commit is contained in:
kai-morich 2024-10-28 21:12:22 +01:00 committed by GitHub
parent 9f93e192ca
commit 0b5950c991
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 69 additions and 2 deletions

View File

@ -203,7 +203,7 @@ public class SerialInputOutputManager implements Runnable {
} }
step(); step();
} }
} catch (Exception e) { } catch (Throwable e) {
if(mSerialPort.isOpen()) { if(mSerialPort.isOpen()) {
Log.w(TAG, "Run ending due to exception: " + e.getMessage(), e); Log.w(TAG, "Run ending due to exception: " + e.getMessage(), e);
} else { } else {
@ -211,7 +211,15 @@ public class SerialInputOutputManager implements Runnable {
} }
final Listener listener = getListener(); final Listener listener = getListener();
if (listener != null) { if (listener != null) {
listener.onRunError(e); try {
if (e instanceof Exception) {
listener.onRunError((Exception) e);
} else {
listener.onRunError(new Exception(e));
}
} catch (Throwable t) {
Log.w(TAG, "Exception in onRunError: " + t.getMessage(), t);
}
} }
} finally { } finally {
synchronized (this) { synchronized (this) {

View File

@ -17,6 +17,11 @@ public class Log {
return 0; return 0;
} }
public static int w(String tag, String msg, Throwable tr) {
System.out.println("WARN: " + tag + ": " + msg + " / " + tr.getMessage());
return 0;
}
public static int e(String tag, String msg) { public static int e(String tag, String msg) {
System.out.println("ERROR: " + tag + ": " + msg); System.out.println("ERROR: " + tag + ": " + msg);
return 0; return 0;

View File

@ -0,0 +1,54 @@
package com.hoho.android.usbserial.util;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import android.hardware.usb.UsbEndpoint;
import android.os.Process;
import com.hoho.android.usbserial.driver.CommonUsbSerialPort;
import org.junit.Test;
public class SerialInputOutputManagerTest {
// catch all Throwables in onNewData() and onRunError()
@Test
public void throwable() throws Exception {
class ExceptionListener implements SerialInputOutputManager.Listener {
public Exception e;
@Override public void onNewData(byte[] data) { throw new RuntimeException("exception1"); }
@Override public void onRunError(Exception e) { this.e = e; throw new RuntimeException("exception2"); }
}
class ErrorListener implements SerialInputOutputManager.Listener {
public Exception e;
@Override public void onNewData(byte[] data) { throw new UnknownError("error1"); }
@Override public void onRunError(Exception e) { this.e = e; throw new UnknownError("error2");}
}
UsbEndpoint readEndpoint = mock(UsbEndpoint.class);
when(readEndpoint.getMaxPacketSize()).thenReturn(16);
CommonUsbSerialPort port = mock(CommonUsbSerialPort.class);
when(port.getReadEndpoint()).thenReturn(readEndpoint);
when(port.read(new byte[16], 0)).thenReturn(1);
SerialInputOutputManager manager = new SerialInputOutputManager(port);
manager.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
ExceptionListener exceptionListener = new ExceptionListener();
manager.setListener(exceptionListener);
manager.run();
assertEquals(RuntimeException.class, exceptionListener.e.getClass());
assertEquals("exception1", exceptionListener.e.getMessage());
ErrorListener errorListener = new ErrorListener();
manager.setListener(errorListener);
manager.run();
assertEquals(Exception.class, errorListener.e.getClass());
assertEquals("java.lang.UnknownError: error1", errorListener.e.getMessage());
assertEquals(UnknownError.class, errorListener.e.getCause().getClass());
assertEquals("error1", errorListener.e.getCause().getMessage());
}
}