The exception thrown is generic and defeats the purpose of exception handling. Each type of exception provides insight into what exactly went wrong and provides scenario-specific ways to recover gracefully. While it is easy to recover from some exceptions, a small subset of them make the recovery very difficult, usually because the conditions are not suitable for the program to continue executing. Be more specific about the exception types you throw.
if (n < 0)
{
throw new Exception("n cannot be < 0");
}
if (n < 0)
{
throw new ArgumentException("n cannot be < 0");
}