C# – When to create a custom exception in C#

cexception handlingexceptions

I'm writing a class to interface with a simple hardware device over a COM port. The device can configured to use various modes, so my class has a SetOperatingMode function, that takes in an enum of type UsbDeviceMode. It looks something like this:

class UsbDevice
{
    public void SetOperatingMode(UsbDeviceMode mode)
    { 
     byte[] buffer = new byte[4];
     buffer[0] = 0x5A;
     buffer[1] = 0x02;
     buffer[2] = (byte)mode;
     buffer[3] = 0x00; //IO_TYPE is always 0 in this case.

     _port.Write(buffer, 0, 4);
     int read = _port.Read(buffer, 0, 2);
     bool successfulSet = (read == 2 && buffer[0] == 0xFF && buffer[1] == 0x00);
    }
}

enum UsbDeviceMode
{
  IO_MODE = 0x00,
  IO_CHANGE = 0x10,
  I2C_S_20KHZ = 0x20,
  I2C_S_50KHZ = 0x30,
  I2C_S_100KHZ = 0x40,
  I2C_S_400KHZ = 0x50,
  I2C_H_100KHZ = 0x60,
  I2C_H_400KHZ = 0x70,
  I2C_H_1000KHZ = 0x80,
  SPI_MODE = 0x90,
  SERIAL = 0x01
};

There is the distinct possibility that this operation might fail due to any number of reasons: The COM port might no longer exist, the device might have locked up or failed, or for whatever reason, the operation failed.

A failure would be unexpected, but not uncommon. There's two distinct modes of failures: The COM port throws an exception (TimeoutException and InvalidOperationException being the expected ones). Or I could read back a failure indicator the device.

In any case, if SetOperatingMode() fails, then the device or the communication is broken somehow, and this class can't do anything about it.

I have 2 questions:

  1. Should I "pre-throw" the InvalidOperationException if the port is closed? From the MSDN documentation, SerialPort.Write and SerialPort read will throw if the port is closed. I can check that at the very top of the function, or I can just let _port.Write() throw it.
  2. Should there be an entirely new exception type thrown when successfulSet is false? If successfulSet is false, there's nothing that this class can do to. Should there be some sort of SetOperatingModeFailedException exception to distinguish between the COM port failing or the device failing? It seems rather time consuming to create an entire exception class just for this one spot.

Best Answer

Use a custom exception when you want users to be able to programmatically distinguish between certain error conditions. If that situation does not exist, you can throw a more "general" exception, and avoid creating the custom exception class.

In the specific case of your SetOperatingMode() example, unless you need to call out specific ways that this method call might fail, you're better off using a more general exception. In other words, if it's your intention to throw a SetOperatingModeFailedException exception as a possible result of calling SetOperatingMode(), but not to programmatically distinguish what kind of operating mode failure occurred, then you can dispense with creating a custom exception (since it's the only one that might be thrown), and simply throw an InvalidOperationException, which is probably the closest existing exception.

If you still want to create a custom exception, create one that is reusable across different methods, like OperationFailedException.

Related Topic