If XmlException.SourceUri is read-only, what good is it?

448 Views Asked by At

I have a couple places in my code where it throwing a new System.Xml.XmlException seems appropriate. I could just do

throw new XmlException("Your XML sucks go fix it then try again.");  

But I think it's better to take advantage whenever possible of members particular to the exception class (otherwise ya might as well throw a plain ol' Exception every time). SourceUri and LineNumber would be helpful, but they only have get methods, there's no way I can assign a value to them! There's only 3 constructor overloads and none of them have parameters for those members either; I can only initialize Message, nothing else.

There has got to be some way to populate those data members with values, otherwise why does XmlException bother with them?

I suppose I could make a new class that inherits XmlException and write a new constructor that initializes SourceUri etc. but still, there must be a way to just use XmlException. Right?

3

There are 3 best solutions below

1
On BEST ANSWER

There is a constructor that takes a sourceUri parameter :

internal XmlException(string res, string[] args, string sourceUri)

But since it is internal, it can only be called inside the System.Xml assembly. Anyway, I don't think you should throw an XmlException yourself. This exception is typically thrown by the XML-related BCL classes. You should rather create your own exception and throw it instead.

1
On

There is a constructor with the line number and line position. I can't see anything that takes SourceUri though...

I believe you can populate it using the serialization streaming context - but that would be pretty fragile.

I think it's best to regard it as something which is effectively only provided by system-thrown XmlExceptions. I don't think that makes it useless - just less flexible than it might be. (I suspect the vast majority of XmlExceptions that are thrown in the world are thrown by the system rather than by user code.)

0
On

I took a look using Reflector, and it would seem that only two constructors set the SourceUri. Those are the deserialization one, and a single internal constructor that sets everything, but all the public ones call that with the SourceUri set to null. Obviously none of those can be easily accessed. I would conclude that there is no good way to set the SourceUri property.