Ivo Renkema Ivo Renkema - 2 years ago 189
Java Question

try ... catch is not catching IllegalArgumentException

In an open-source Camera App, I have a crash at the following code

try {
// crash happens in next line:
PtpUsbConnection connection = new PtpUsbConnection(usbManager.openDevice(device), in, out,
device.getVendorId(), device.getProductId());
camera = new EosCamera(connection, listener, new WorkerNotifier(context));
}
catch (IllegalArgumentException e) {
Log.i(TAG, "IllegalArgumentException: camera was switched off? "+ e.getMessage());
e.printStackTrace();
return false;
}
catch (Exception e) {
Log.i(TAG, "Exception: camera was switched off? "+ e.getMessage());
e.printStackTrace();
return false;
}


The crash produces the following log

02-25 10:41:14.698 9238-9238/com.remoteyourcam.usb E/UsbManager´╣Ľ exception in UsbManager.openDevice
java.lang.IllegalArgumentException: device /dev/bus/usb/001/008 does not exist or is restricted
at android.os.Parcel.readException(Parcel.java:1469)
at android.os.Parcel.readException(Parcel.java:1419)
at android.hardware.usb.IUsbManager$Stub$Proxy.openDevice(IUsbManager.java:373)
at android.hardware.usb.UsbManager.openDevice(UsbManager.java:308)
at com.remoteyourcam.usb.ptp.PtpUsbService.connect(PtpUsbService.java:238)
at com.remoteyourcam.usb.ptp.PtpUsbService.initialize(PtpUsbService.java:135)
at com.remoteyourcam.usb.MainActivity.onStart(MainActivity.java:232)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1171)
at android.app.Activity.performStart(Activity.java:5413)
at android.app.Activity.performRestart(Activity.java:5469)
at android.app.Activity.performResume(Activity.java:5474)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2945)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2984)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1335)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:149)
at android.app.ActivityThread.main(ActivityThread.java:5257)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:788)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:604)
at dalvik.system.NativeStart.main(Native Method)


There is a reproducible sequence of events which causes the crash. Specifically: switching of the camera on the USB bus when the App (apparently) does not foresee the possibility.

I was hoping to simply catch this Exception and then ignore it.

However, even though the code explicity catches
IllegalArgumentException
and also (for good measure) the general
Exception
, the App simply continues to crash.

Why is my
IllegalArgumentException
not being caught?


---- update:

The openDevice() method is part of Android Library. It actually seems to handle
Exception
.

Here are my imports

package com.remoteyourcam.usb.ptp;

import java.util.Map;

import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.usb.UsbConstants;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbEndpoint;
import android.hardware.usb.UsbInterface;
import android.hardware.usb.UsbManager;
import android.os.Handler;
import android.util.Log;

import com.remoteyourcam.usb.AppConfig;
import com.remoteyourcam.usb.ptp.Camera.CameraListener;
import com.remoteyourcam.usb.ptp.PtpCamera.State;


---- update 2:

This is the
openDevice()
implementation I see in Android 18. As far as I can tell, it handles a general
Exception


/**
* Opens the device so it can be used to send and receive
* data using {@link android.hardware.usb.UsbRequest}.
*
* @param device the device to open
* @return a {@link UsbDeviceConnection}, or {@code null} if open failed
*/
public UsbDeviceConnection openDevice(UsbDevice device) {
try {
String deviceName = device.getDeviceName();
ParcelFileDescriptor pfd = mService.openDevice(deviceName);
if (pfd != null) {
UsbDeviceConnection connection = new UsbDeviceConnection(device);
boolean result = connection.open(deviceName, pfd);
pfd.close();
if (result) {
return connection;
}
}
} catch (Exception e) {
Log.e(TAG, "exception in UsbManager.openDevice", e);
}
return null;
}

Answer Source

The Exception is happening in another thread.

You are initializing and dispatching work to another thread asynchronously. Your code only catches exceptions in dispatching the Parcel to the remote Service.

For more information about remote procedure calls in Android you might want to read Deep Dive into Binder.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download