I'm currently working through a series of bugs in an application. Our application is written in C#/ASP.NET (on the server) and HTML/CSS/JavaScript (on the client). We are using ELMAH to log any uncaught exceptions in the system so that we may identify it later and fix it, which is what I'm currently doing.
The way ELMAH works is to log any uncaught exception, so once you catch and handle the exception, it can be omitted from ELMAH.
This article closely relates to a question I asked here on Stack Overflow.
To give a little bit of insight into this article, ELMAH logs uncaught exceptions, but sometimes you have certain scenarios where the exception is thrown to the browser and handled there. ELMAH doesn't know that it's being handled elsewhere, so it still logs the exception.
In our application, we use WCF web services to send JSON data back to the client. Say for example one of those services fails and throws an exception, we send that exception back to the browser and handle it there (and as stated, ELMAH still logs it).
So I had this idea, which might only apply to a small set of use cases, but as an idea, I wanted to know what the community thought of it.
As OO programmers know, methods/functions have a return type (or void
).
Example
public void SayHello() { Print("Hello"); } public string GetMyName() { return "Joe Bloggs"; }
All well and good so far, but what if I wanted my method/function to return either a value, or an exception if one was to occur? I can do this in C# using the dynamic keyword.
Example
public dynamic GetMyNameOrCryLikeABaby() { try { return DoSomethingWrong(); // might throw an exception, but should return a string. } catch(Exception ex) { return ex; } }
Personally I don't like this approach. I don't think it is a good use of the dynamic keyword, and it involves the developer adding in additional code to check whether the return value was (in this example) a string, or an Exception.
The idea I came up with to get around this was based somewhat on .NET's Nullable<T>
structure. The idea here being that a ValueType wrapped in a Nullable<T>
(e.g. Nullable<int>
) can return null.
The structure below has some interesting characteristics! The aim was to write a structure that could implicitly be cast to the expected type, but could also return an exception, should one occur. This structure is called "Exceptable" meaning it might hold an exception.
Exceptable<T>
Source Code
/// <summary>
/// Represents a generic type that can also hold an associated exception.
/// </summary>
/// <typeparam name="T">The type of this Exceptable object.</typeparam>
public struct Exceptable<T>
{
/// <summary>
/// Gets or sets the value of this object.
/// </summary>
public T Value { get; set; }
/// <summary>
/// Gets or sets an exception that may occur when using this type.
/// </summary>
public Exception Exception { get; set; }
/// <summary>
/// Gets a value indicating whether this object has a value.
/// </summary>
public Boolean HasValue
{
get { return this.Value != null; }
}
/// <summary>
/// Gets a value indicating whether this object has an exception.
/// </summary>
public Boolean HasException
{
get
{
return this.Exception != null;
}
}
/// <summary>
/// Allows implicit casting between a raw type, and an Exceptable type.
/// </summary>
/// <param name="value">The exceptable value to convert to a raw type.</param>
/// <returns>A raw type</returns>
public static implicit operator T(Exceptable<T> value)
{
return value.Value;
}
/// <summary>
/// Allows implicit casting between an Exceptable type and a raw type.
/// </summary>
/// <param name="value">The raw type to convert to an excepable type.</param>
/// <returns>An excepable type.</returns>
public static implicit operator Exceptable<T>(T value)
{
return new Exceptable<T>
{
Value = value
};
}
}
So as you can see here, it wraps the expected type into Exceptable
as a generic type and provides implicit conversion between Exceptable<T>
and T
.
Use Cases
Exceptable<string> name = "Joe Bloggs";
Exceptable<int> age = 26;
public static Exceptable<string> GetMyNameOrCryLikeABaby()
{
Exceptable<string> result = String.Empty;
try
{
result = DoSomethingWrong() // might throw an exception but should return a string.
}
catch(Exception ex)
{
result.Exception = ex;
}
return result;
}
string name = GetMyNameOrCryLikeABaby();
Exceptable<string> nameOrException = GetMyNameOrCryLikeABaby();
As you can see from the examples above, I can assign values directly to Exceptable<T>
. I can also use it as a return type for a method, and due to implicit conversion, I can choose whether to return just the associated value of the structure, or the structure itself, in case I want to handle the associated exception.
What do you think?
bind
, or anything similar. \$\endgroup\$