The System.Exception class (actually any exception) has Data property which is almost always empty. While throwing exceptions, should this field be of any use? Or does it have some internal use that I am not aware of?
The documentation seems clear enough as to its use (emphasis added):
Gets a collection of key/value pairs that provide additional user-defined information about the exception.
Why does it exist in the first place? I assume it's the same reason Control has a Tag property. In the early days of .NET (before every Bob and Betty programmer understood objects and inheritance) they wanted to make the API simple enough that everyone could figure out how to add extra data to things.
However, the point of creating custom exceptions that derive from System.Exception is not necessarily to include additional information, but to make it possible for the client to limit the exceptions they catch to only those that they can handle. If they know how to handle a set of defined exceptions that your code can throw, they should be able to only catch those exceptions, without having to catch the base System.Exception class. What you should definitely never do is require the client code to catch a non-specific exception class and read a property to determine what type of exception it is (and thus whether or not they are able to handle it).
I've honestly never used this property before. I had to check the documentation to even see that it did indeed exist. But I imagine it's most useful for implementing custom exception logging. You can embed a lot of important information into the Data property (regardless of the level of derivation of exception class), and then pass that off to your logging code. Reflector indicates that it's used internally in a handful of places for precisely that purpose. It's also nice that all the information you provide here gets correctly serialized for you automatically.
Another note here, what I do when I inherit an exception and add properties, is to make the properties actually get and set from the data dictionary, and not from local variables.
[Serializable]
public class PacketParseException : Exception
{
public byte[] ByteData
{
get
{
return (byte[])this.Data["ByteData"];
}
}
public PacketParseException(string message, byte[] data, Exception inner) : base(message, inner)
{
this.Data.Add("ByteData", data);
}
}
The way I see it, then the internal data is available from an Exception as well, for example when logging, so no need to cast to actual type.
With the new CallerMemberNameAttribute it's even easier to use the Data property for storage:
public class BetterException : Exception
{
protected T GetValue<T>([CallerMemberNameAttribute] string propertyName = "")
{
return (T)Data[propertyName];
}
protected void SetValue<T>(T value, [CallerMemberNameAttribute] string propertyName = "")
{
Data[propertyName] = value;
}
}
Usage:
class MyException : BetterException
{
public MyException(string name)
{
Name = name;
}
public string Name
{
get { return GetValue<string>(); }
set { SetValue(value); }
}
}
Related
I have a scenario where I normally retrieve an object, let's call it UserRights.
If everything is fine the object is populated.
BUT if something goes wrong i want to know that something went wrong and why. Normally I'd throw an exception, but I cannot throw exceptions up for various reasons.
I was thinking of adding two fields to the returning object, ErrorCode (int) and ErrorReason (string).
If Errorcode==0 then everything is fine and the object is populated. but if it is not 0 then something went wrong and i need to look at ErrorReason to see why.
The biggest problem i can see with this is that i have to update every single object and it's calls to cater for these extra fields.
Are there any other potential ways of returning error data better that this?
I don't know your application architecture, so it is difficult to say for certain but you have some options;
Option 1
Define a base class, and then all your other classes can inherit from this;
public class MyBase {
public int ErrorCode { get; set; }
public string ErrorMessage { get; set; }
public MyBase ()
{
ErrorCode = 0;
ErrorMessage = null; // or "";
}
}
Then you limit the effort to only needing to update these IF you have an error.
But you do have to update all of your other classes to inherit from this. (A pain if you have a lot, then you can use option 2 below)
Option 2
If you have only a few places where you return your result, then you can modify your response before you send it.
Define the same class as above, but include an extra property for your response. Such as this;
public object MyResponse { get; set; }
Then, when you return your result create an instance of this class. If you have errors update them and leave MyResponse as null.
Else, put your normal response object in MyResponse and return it.
Option 3
Define the same class as above but don't inherit from it.
Change your response so that you return a generic object.
When you return your object, return either the correct object or in the case of errors return only the Error object.
Then your receiving function needs to determine the type of class returned and deal with it.
Option 4
You could have separate error reporting.
When you have an error you just a reference number, and log your error somewhere else.
The receiver gets this reference number instead of a result, and then does a look up to determine what the actual error was.
I've got the following code which retrieves a records details when I click on a table grid:
public ActionResult City(string rk)
{
try
{
var city = _cityService.Get("0001I", rk);
if (city == null)
{
throw new ServiceException("", "Error when fetching city " + rk);
}
}
}
What kind of exception should I use for this "no record found" problem? I see there are different kinds of exception, but I am not sure which would be appropriate or even if I am coding this correctly.
KeyNotFoundException would be a reasonable choice, and would conform to the Microsoft guideline to:
Consider throwing existing exceptions residing in the System namespaces instead of creating custom exception types.
However you could consider creating your own Exception type if (again from the Microsoft guidelines):
... you have an error condition that can be programmatically handled in a different way than any other existing exceptions.
If you do create your own Exception, you should follow the guidelines for designing custom exceptions, e.g. you should make your Exception type Serializable.
You should create your own exception, and maybe call it RecordNotFoundException in this case.
Creating your own exception is quite easy. Just make a class, give it a name, extend Exception or some other exception type, and provide the constructors that you need (just calling the base Exception constructors).
If you want to add more, you can, but you often don't need to.
If you find yourself creating a number of exceptions for your project you may want to create a base exception type (that extends Exception) which all of your exceptions extend. This is something you might do when writing a library. It would allow someone to catch either a specific exception, or an exception thrown from your library, or any exception.
public class MySuperAwesomeException : Exception
{
public MySuperAwesomeException() : base() { }
public MySuperAwesomeException(string message) : base(message) { }
public MySuperAwesomeException(string message, Exception innerException)
: base(message, innerException) { }
}
I have decided to use Exceptions in my code to pass error handling around. I found myself duplicating code each time I wanted to create a new exception. These classes were nothing special and only contained a messaged. But I have come to rely on type safety when handing them. Is there a way to provide a new exception class type without having to re-implement the constructors?
[Serializable]
class MyNewException : MyBaseException
{
public MyNewException (String tMsg)
: base(tMsg)
{
}
public MyNewException (String tMsg, Exception tInnerEx)
: base(tMsg, tInnerEx)
{
}
}
The code above is duplicated many times over for each different type of exception I want to define.
Unfortunately, no, the constructors have to be provided since they are not inherited.
In addition, unless you are catching these specific exceptions and performing explicit processing when they occur, I would recommend having a generic exception that contains the additional information that you might need. However, this may not apply in your case.
In .net, c#
There are many sub-classes of Exception already existing,
what are they and when do we use them instead of creating our own sub-class?
This question is duplicate of c# is there an exception overview
The link provided by Jason is pretty comprehensive, but a lot of the exception types in it (such as NullReferenceException or IndexOutOfRangeException) are really only ever thrown by the framework; it would not be very appropriate for you was a developer to explicitly throw them.
Here are, in my opinion, a handful of the most useful exception types for a developer.
ArgumentNullException
This one's obvious: one of the arguments passed to a method was null, but for this particular method, a null value for that argument is not allowed.
ArgumentOutOfRangeException
A value was supplied to a method that is outside of the range that makes sense for that method.
Example
In most methods that take a parameter representing a magnitude or length, only positive values make sense for that parameter. So a check such as
if (x < 1)
{
throw new ArgumentOutOfRangeException("x");
}
is common.
FormatException
This is a pretty reasonable choice when you're writing your own custom text-parsing method, or really any code that expects strings to match a certain format, and some input is supplied that the code can't understand.
InvalidOperationException
I tend to use this one a lot (probably overuse it, actually) whenever I'm not sure what else to use. Generally I think of this type as conveying that the client attempted to do something illegal, for reasons relevant to the current class or method.
Example
Many IEnumerator<T> implementations throw an InvalidOperationException when the collection they're enumerating is modified. This is a reasonable design choice, as it is much easier to design a collection class that does not handle this case than it is to design one that does.
NotSupportedException
This one typically makes sense in a class that derives from some base class and only offers a partial implementation of that base class's abstract members.
Example
Some developers choose to write base classes with "optional" functionality that may be provided by derived classes or may not be. Below is an example:
abstract class Animal : Organism
{
public virtual bool EatsPlants
{
get { return false; }
}
public virtual void EatPlant(Plant food)
{
throw new NotSupportedException();
}
public virtual bool EatsAnimals
{
get { return false; }
}
public virtual void EatAnimal(Animal food)
{
throw new NotSupportedException();
}
}
class Herbivore : Animal
{
public override bool EatsPlants
{
get { return true; }
}
public override void EatPlant(Plant food)
{
// whatever
}
}
Obviously this is just my own personal (and subjective) list; but I thought it might give you an idea of what kinds of exceptions you can and should be leveraging within your own code.
Here is list of common exception types. If you want to know when to create your own exceptions, then try:
What are some best practices for creating my own custom exception?
For a list of sub-classes of Exception I recommend that you use the .NET Reflector.
http://www.red-gate.com/products/reflector/
I have a class with various public properties which I allow users to edit through a property grid. For persistence this class is also serialized/deserialized to/from an XML file through DataContractSerializer.
Sometimes I want to user to be able to save (serialize) changes they've made to an instance of the class. Yet at other times I don't want to allow the user to save their changes, and should instead see all the properties in the property grid as read only. I don't want to allow users to make changes that they'll never be able to save later. Similar to how MS Word will allow users to open documents that are currently opened by someone else but only as read only.
My class has a boolean property that determines if the class should be read-only, but is it possible to use this property to somehow dynamically add a read-only attributes to the class properties at run-time? If not what is an alternative solution? Should I wrap my class in a read-only wrapper class?
Immutability is an area where C# still has room to improve. While creating simple immutable types with readonly properties is possible, once you need more sophisticated control over when type are mutable you start running into obstacles.
There are three choices that you have, depending on how strongly you need to "enforce" read-only behavior:
Use a read-only flag in your type (like you're doing) and let the caller be responsible for not attempting to change properties on the type - if a write attempt is made, throw an exception.
Create a read-only interface and have your type implement it. This way you can pass the type via that interface to code that should only perform reads.
Create a wrapper class that aggregates your type and only exposes read operations.
The first option is often the easiest, in that it can require less refactoring of existing code, but offers the least opportunity for the author of a type to inform consumers when an instance is immutable versus when it is not. This option also offers the least support from the compiler in detecting inappropriate use - and relegates error detection to runtime.
The second option is convenient, since implementing an interface is possible without much refactoring effort. Unfortunately, callers can still cast to the underlying type and attempt to write against it. Often, this option is combined with a read-only flag to ensure the immutability is not violated.
The third option is the strongest, as far as enforcement goes, but it can result in duplication of code and is more of a refactoring effort. Often, it's useful to combine option 2 and 3, to make the relationship between the read-only wrapper and the mutable type polymorphic.
Personally, I tend to prefer the third option when writing new code where I expect to need to enforce immutability. I like the fact that it's impossible to "cast-away" the immutable wrapper, and it often allows you to avoid writing messy if-read-only-throw-exception checks into every setter.
If you are creating a library, it is possible to define a public interface with a private/internal class. Any method which needs to return an instance of your read-only class to an external consumer should instead return an instance of the read-only interface instead. Now, down-casting to a concrete type is impossible since the type isn't publicly exposed.
Utility Library
public interface IReadOnlyClass
{
string SomeProperty { get; }
int Foo();
}
public interface IMutableClass
{
string SomeProperty { set; }
void Foo( int arg );
}
Your Library
internal MyReadOnlyClass : IReadOnlyClass, IMutableClass
{
public string SomeProperty { get; set; }
public int Foo()
{
return 4; // chosen by fair dice roll
// guaranteed to be random
}
public void Foo( int arg )
{
this.SomeProperty = arg.ToString();
}
}
public SomeClass
{
private MyThing = new MyReadOnlyClass();
public IReadOnlyClass GetThing
{
get
{
return MyThing as IReadOnlyClass;
}
}
public IMutableClass GetATotallyDifferentThing
{
get
{
return MyThing as IMutableClass
}
}
}
Now, anyone who uses SomeClass will get back what looks like two different objects. Of course, they could use reflection to see the underlying types, which would tell them that this is really the same object with the same type. But the definition of that type is private in an external library. At this point, it is still technically possible to get at the definition, but it requires Heavy Wizardry to pull off.
Depending on your project, you could combine the above libraries into one. There is nothing preventing that; just don't include the above code in whatever DLL you want to restrict the permissions of.
Credit to XKCD for the comments.
Why not something like:
private int someValue;
public int SomeValue
{
get
{
return someValue;
}
set
{
if(ReadOnly)
throw new InvalidOperationException("Object is readonly");
someValue= value;
}
I would use a wrapper class that keeps everything read-only. This is for scalability, reliability and general readability.
I do not foresee any other methods of doing this that will provide the above three mentioned benefits as well as something more. Definitely use a wrapper class here in my opinion.
You can not get compile-time checks (like given with the keyword readonly) by changing a property to readonly at runtime. So there is no other way, as to check manually and throw an exception.
But propably it is better to re-design access to the class. For example create a "writer class", which checks if the underling "data class" can currently be written or not.
You can use PostSharp to create OnFieldAccessAspect that will not pass new value to any field when _readOnly will be set to true. With aspect code repetition is gone and there will be no field forgotten.
Would something like this help:
class Class1
{
private bool _isReadOnly;
private int _property1;
public int Property1
{
get
{
return _property1;
}
set
{
if (_isReadOnly)
throw new Exception("At the moment this is ready only property.");
_property1 = value;
}
}
}
You need to catch exceptions when setting properties.
I hope this is something you are looking for.