Skip to content

Commit

Permalink
catch all Throwables from SerialInputOutputManager.Listener methods (#…
Browse files Browse the repository at this point in the history
…601) (#606)

to avoid breaking Interface changes, Error from onNewData() is wrapped into Exception when calling onRunError()
  • Loading branch information
kai-morich authored Oct 28, 2024
1 parent 9f93e19 commit 0b5950c
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -203,15 +203,23 @@ public void run() {
}
step();
}
} catch (Exception e) {
} catch (Throwable e) {
if(mSerialPort.isOpen()) {
Log.w(TAG, "Run ending due to exception: " + e.getMessage(), e);
} else {
Log.i(TAG, "Socket closed");
}
final Listener listener = getListener();
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 {
synchronized (this) {
Expand Down
5 changes: 5 additions & 0 deletions usbSerialForAndroid/src/test/java/android/util/Log.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ public static int w(String tag, String msg) {
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) {
System.out.println("ERROR: " + tag + ": " + msg);
return 0;
Expand Down
Original file line number Diff line number Diff line change
@@ -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());
}
}

0 comments on commit 0b5950c

Please sign in to comment.