mercredi 8 février 2017

Which exception type to use for a sanity check?

Vote count: 0

I'm writing software in .NET which requires runtime sanity checks, even in release mode, which means Debug.Assert and Trace.Assert are inappropriate (as Debug.Assert only works when the DEBUG symbol is defined, and Trace.Assert doesn't cause program termination).

An immediate solution is to use Environment.FailFast with an explanatory message, but I'd prefer to throw some kind of exception - and I'd really not like to throw my own custom exception because my code could be called by other code which does not have a reference to my assembly, so they would be unable to catch it without catching System.Exception.

Surprisingly, the standard .NET Framework does not ship with any kind of RuntimeAssertException, ThisShouldNeverHappenException or UnacceptableUnexpectedDataException - granted, that's what System.Exception is meant to represent ("exceptional" circumstances) - except Best Practices prohibit throwing System.Exception directly. Furthermore ApplicationException is effectively deprecated and is only meant for use in non-fatal situations:

http://ift.tt/2koxXJN

ApplicationException Class - The exception that is thrown when a non-fatal application error occurs.

Using InvalidOperationException is a cop-out, but it isn't entirely appropriate because my particular scenario relates to incoming data.

Here's an example:

public void ProcessData() {

    // Input:
    MyDataType incomingData = this.dataSource.ReadFromExternalSource();

    // Sanity check:
    if( incomingData.Foo != 1 ) throw ...;
    if( incomingData.Bar != "baz" ) throw ...;
    if( incomingData.Items.Count <= 123 ) throw ...;

    // Do work:
    this.turboEncabulator.ApplyCapacitativeDiractance( incomingData.Bar, ref incomingData.Foo );

    // Output:
    this.dataSink.Output( incomingData );
}

  • Using ArgumentException is inappropriate because the incomingData is not actually an argument.
    • While there is ArgumentOutOfRangeException there is no LocalVariableOutOfRangeException which might be more appropriate.
  • In this contrived example, InvalidOperationException would be valid as it concerns to the state of incomingData, but in my example the interaction between objects is more complex.
  • As the TurboEncabulator just processes raw numbers, it's the responsibility of the ProcessData method to ensure the data is within the correct domain bounds, which is why ApplyCapacitativeDiractance won't throw any ArgumentException values.
asked 8 secs ago

Let's block ads! (Why?)



Which exception type to use for a sanity check?

Aucun commentaire:

Enregistrer un commentaire