Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting fields on a exception while complying with CA 1032

CA1032 says each exception must have the following constructors:

public NewException()
public NewException(string)
public NewException(string, Exception)
protected or private NewException(SerializationInfo, StreamingContext)

However, in this case I want to capture some ExceptionContext which has some more information. Currently my code looks like this:

public class NewException : Exception {
  public NewException(ExceptionContext context) 
    : base() {
    if (context == null) throw new ArgumentNullException("context");
    this.context = context;
  }
}

How do I ensure that an ExceptionContext is set on the NewException while still complying with CA1032?

I could set the context in a property:

public class NewException : Exception {
  public ExceptionContext Context { get { /*get*/ } set { /*null check and set*/ } }
  /*Standard constructors...*/
}

but now the is no way to make a caller set a ExceptionContext, the class is more verbose because I have to have a backing variable (or no null check on the property), and NewException is mutable.

I notice the "When to suppress" section says:

It is safe to suppress a warning from this rule when the violation is caused by using a different access level for the public constructors.

I am not quite sure what is meant by this. Is this saying that I am allowed to write something like this, and then suppress the analysis?

public class NewException : Exception {
  public NewException(ExceptionContext context) 
    : this() {
    if (context == null) throw new ArgumentNullException("context");
    this.context = context;
  }

  private NewException() 
    : base() { }

  public NewException(ExceptionContext context, string message) 
    : this(message) {
    if (context == null) throw new ArgumentNullException("context");
    this.context = context;
  }

  private NewException(string message) 
    : base(message) { }
  ...
}

Edit/additional question: Do I need to implement NewException(ExceptionContext, SerializationInfo, StreamingContext) or is the point of the SerializationInfo to store other state?

protected NewException(SerializationInfo info, StreamingContext context) 
  : base (info, context) {
  this.context = new ExceptionContext();
  this.context.Field1 = (T1)info.GetValue("Field1", typeof(T1));
  ...
}
like image 284
Jonny Avatar asked Nov 15 '25 20:11

Jonny


1 Answers

The logic behind that rule is that there should be a standard way to construct exception objects. (I'll admit I don't understand the purpose of that logic, but that's not relevant here.) There may also be additional ways specific to your exception classes, but the standard ways should always work.

In your case, if you want to construct a NewException object but don't have any ExceptionContext to pass, what do you want your NewException object to do?

If you want to disallow that, then you don't want your exception objects to behave like standard exception objects, and should disable any warnings about that fact.

If you want to allow that, then you need to provide the standard constructor overloads, and do whatever seems best for your specific classes.


Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!