Ryan Harrison My blog, portfolio and technology related ramblings

C# - Re-throwing Exceptions

In C# it is common that exceptions are re-thrown after some logging has taken place, or perhaps even to alter the exception information to be more user friendly. However there are two different ways of re-throwing exceptions in C# and care needs to be taken when doing so, as one method will loose the stack trace - making things a lot harder to debug.

Consider the following code:

  
using System;

namespace ScratchPad  
{  
    internal class Throwing  
    {  
        // Some method which can throw an exception  
        static void DoSomething()  
        {  
            throw new Exception("Something bad happened");  
        }

        // Another method which tries calling the other method, catching an exceptions it may throw  
        static void Run()  
        {  
            try  
            {  
                Console.WriteLine("Trying to run DoSomething()");  
                DoSomething();  
            }  
            catch (Exception e)  
            {  
                // We caught the exception. Typically some logging is taken place here  
                Console.WriteLine("We caught an exception in DoSomething(). Message = " + e.Message);  
                Console.WriteLine("Re throwing the exception after logging");

                // We then re-throw the exception  
                throw e;  
            }  
        }

        static void Main()  
        {  
            try  
            {  
                // Run the method  
                Run();  
            }  
            catch (Exception e)  
            {  
                // We catch the exception here and examine its stack trace  
                Console.WriteLine("We caught the exception. Stack trace is");  
                Console.WriteLine();  
                Console.WriteLine(e.StackTrace);  
            }

            Console.ReadLine();  
        }  
    }  
}  

This is pretty self-explanatory. We have a method that runs another method and catches any exceptions it may throw (in this case one will be thrown every time). In the catch block we examine the exception, perhaps do some logging and re-throw the exception for the caller to handle. Finally in Main the re-thrown exception is caught again and the stack trace is examined.

At first look there is nothing wrong with this code, it’s all pretty commonplace, nothing much to see here. However this is the output that we get:

  
Trying to run DoSomething()  
We caught an exception in DoSomething(). Message =: Something bad happened  
Re throwing the exception after logging  
We caught the exception. Stack trace is

at ScratchPad.Throwing.Run() in C:\Code\ScratchPad\ScratchPad\Program.cs:line 28  
at ScratchPad.Throwing.Main() in C:\Code\ScratchPad\ScratchPad\Program.cs:line 37  

You may or may not have noticed that this is not the full stack trace. We can see that the exception came from Run(), however we can’t tell that in actual fact the exception originated from DoSomething() at all. This may or may not cause problems when debugging as now instead of going straight to the route cause, you first have to go through Run().

We lose the top of the stack trace because we used

  
throw e;  

Which essentially resets the stack trace to now start in that method. This makes sense as this is really the same as doing something like:

  
throw new Exception(e.Message);  

But what if we wanted to see the whole stack trace? Well instead of using throw e; we just use:

  
throw;  

With the updated catch block:

  
catch (Exception e)  
{  
    // We caught the exception. Typically some logging is taken place here  
    Console.WriteLine("We caught an exception in DoSomething(). Message = " + e.Message);  
    Console.WriteLine("Re throwing the exception after logging");

    // We then re-throw the exception  
    throw;  
}  

We get the output:

  
Trying to run DoSomething()  
We caught an exception in DoSomething(). Message = Something bad happened  
Re throwing the exception after logging  
We caught the exception. Stack trace is

at ScratchPad.Throwing.DoSomething() in C:\Code\ScratchPad\ScratchPad\Program.cs:line 10  
at ScratchPad.Throwing.Run() in C:\Code\ScratchPad\ScratchPad\Program.cs:line 28  
at ScratchPad.Throwing.Main() in C:\Code\ScratchPad\ScratchPad\Program.cs:line 37  

We now have the full story in the stack trace. We can see that the exception originated from the DoSomething() method and passed through the Run() method into Main() - much more helpful when debugging.

I don’t see any situation when using throw e; would be of any use at all. If you wanted to hide the stack trace then you would typically be throwing a completely new exception anyway - with a new message and perhaps other information to pass to the caller. If you didn’t want to hide the stack trace then throw; is the statement to use. Resharper even sees throw e; as a problem and tries to replace it with the simple throw;.

Even so I bet this mistake has been made a lot of times by a lot of people. So remember if you are wanting to re-throw an exception, never use throw e; as it will loose your stack trace. Instead always use throw;.

Read More

C# - String concatenation instead of StringBuilders

In C# when you concatenate two strings together you are implicitly creating a lot of strings in memory - more than you would have thought. For example consider the code:

  
List<string> values = new List<string>() {"foo ", "bar ","baz"};
string output = string.Empty;
foreach (var value in values)
{ 
    output += value; 
} 

Behind the scenes new strings are created for each portion of the resulting string in completely different memory locations through inefficient copy operations. So in total in this one line we have created: 1. "foo" 2. "bar" 3 "baz" 4 "foo bar" 5. "foo bar baz" In just one seemingly simple concatenation loop 5 strings have been created which of course is wildly inefficient. The problem gets a lot worse when you end up concatenating hundreds of strings together in a loop like this. The solution is to use StringBuilders. The above code is converted into:

 
List<string> values = new List<string>() {"foo ", "bar ","baz"};
StringBuilder builder = new StringBuilder();
foreach (var value in values)
{
    builder.Append(value);
} 

Using this method is a lot more efficient thanks to the fact that StringBuilders keep the same position in memory for their strings and do not perform inefficient copy operations each time a new string is appended (for example number 4 from above would not be created in a completely separate memory location). This makes StringBuilders very useful when concatenating many strings at once. But that doesn’t mean go replace all of your string concatenation code with StringBuilders right away. There are some situations where explicitly using a StringBuilder can make the situation worse. For example:

string result = "foo " + "bar " + "baz";

You might think that this suffers with the same inefficiencies as in the first example but in fact it doesn’t at all. The difference is that compile-time concatenations (which is what’s happening here) are automatically translated by the compiler into the appropriate calls to String.Concat() (which is the fastest way). Adding a StringBuilder would essentially be ruining the optimisations made by the compiler. The use of StringBuilder should be reserved to building complex strings at runtime - not replacing compile time concatenations.

Read More

C# - Casting with (T) vs. as (T)

In C# there are two methods for casting:

  1. (T) works with both value and reference types. It casts the object to T, and throws an InvalidCastException if the cast isn’t valid.
    e.g -; Foo obj = (Foo) bar;
  2. as (T) works only with reference types. It returns the object casted to T if it succeeds, and null if the cast isn’t valid.
    e.g -;
Foo obj = bar as Foo;  
if(obj == null)
{  
  // the cast did not succeed so proceed accordingly  
}  

The question therefore is which one should be used where?

Using (T) means that you fully expect the cast to succeed. If it doesn’t succeed then there is an error in the code that needs looking at.

Using as (T) on the other hand means that you do not fully expect the cast to succeed in every case. It is considered normal behaviour if the cast did not succeed and this would be taken care of through a null check afterwards.

The only mistake is when you use as (T) but do not follow it up with a null check. The developer fully expects the cast to succeed so doesn’t write the null check. However later down the line when something goes wrong, no exception is thrown on the invalid cast, no null check is performed, and you have yourself a bug that is hard to track down. It is best to always use the regular cast (T) unless you intend to check yourself for the invalid cast via as (T) and a null check afterwards.

Read More

CryptoLocker - Malware That Encrypts Your Data

So apparently there is a new bit of malware going around now which is particularly nasty. It encrypts all of the data on your drive and mapped network drives with an RSA 256 bit AES key. Once encrypted there is obviously no way to decrypt it again. The only way to get the files back is from an off site backup (because if the backup drive is local it also gets encrypted) or to pay them their ransom which would of course decrypt your files (not). The fact that this also attacks networked drives is particularly annoying and I bet this would catch a lot of people out if they were to get infected.

CryptoLocker Screenshot

Source and More Info

Read More

Git Bash - Refer to files without absolute paths

When using the Git version control system with Git Bash it can often become annoying when you have to manually type in the full absolute paths to particular files in your project. For example when trying to add changes to the staging area or checking out a file, in a large project typing out the full file path can be very tedious:

git add src/uk/co/ryanharrison/snippetmanager/SnippetManager.java

or

git checkout src/uk/co/ryanharrison/snippetmanager/Snippet.java

The problem is especially bad when working on Java projects as the folder structure follows the package names which can often get rather long.

Handily there is an alternative when using Git Bash to all this typing - the ‘*’ or ‘2-asterisk globstar; which searches recursively down your file structure for a file matching the given name.

The above commands can then be replaced with:

git add **/SnippetManager.java

which will add any file called SnippetManager.java Bash finds below the current working directory to the staging area. The same works with all other commands:

git checkout **/Snippet.java

Apparently for this to work in Bash you first have to activate globstar using this command:

shopt -s globstar

however the Git Bash in Windows does not seem to support this. The functionality seems to still work though, at least when using it within Git commands.

Read More