views:

163

answers:

6

I have a method which accepts a filename as a parameter, all filenames should end with '.csv'. Which exception should I throw if a filename that does not end with .csv is passed?

Or should I take a different approach?

+10  A: 

ArgumentException would fit the bill IMO.

Brian Rasmussen
+7  A: 

I'd probably use ArgumentException, as it's "The exception that is thrown when one of the arguments provided to a method is not valid"

Adam Wright
+1  A: 

System.ArgumentException appears appropriate, either directly or as a base class for your exception.

MSalters
+4  A: 

Check the documentation of an existing IO method in the Framework. It describes the exceptions generated by a method. For example, check StreamWriter.StreamWriter(String, Boolean, Encoding, Int32) Constructor at http://msdn.microsoft.com/en-us/library/0wf7ab94%28VS.85%29.aspx. The exception I suggest you use, to remain consistent, is IOException. You can then add a custom message that describes the particulars.

IOException - path includes an incorrect or invalid syntax for file name, directory name, or volume label syntax.

In your case, the file extension is incorrect, so tell the user, as in Throw New IOException("Invalid file extension.").

I would leave ArgumentException as described in the documentation, path is an empty string ("")."

See Choosing the Right Type of Exception to Throw at http://msdn.microsoft.com/en-us/library/ms229021.aspx.

AMissico
That's a good point. I'm not too happy with how the framework handles this, but if you want to be consistent with the Stream classes it may be a good idea to do this (assuming the method in question is actually related to IO)
Brian Rasmussen
Agreed, but after I got use to the IO exceptions, I don't mind it too much. One benefit of leaving ArgumentException as defined would allow for easy debugging when filename is really "".
AMissico
No, an incorrect (but valid) extension isn't an IOExcpetion. It's a broken constraint at this level.
Henk Holterman
Good point. Yet...I am more trying to point the developer to look at existing documentation for guidance.
AMissico
+1  A: 

How about just creating your own InvalidFilenameException? For example:

public class InvalidFilenameException : Exception
{
    public string Filename { get; private set; }

    public InvalidFilenameException(string message, string invalidFilename)
        :base(message)
    {
        Filename = invalidFilename;
    }
}
Svish
The more code you write, the more potential for bugs, the more time it takes, the more decisions have to be made. Unless there is a specific need for a custom exception, it is better to avoid them.
AMissico
Well, of course. But if I find it clearer to create your own Exception if you can't really find anyone that really fits. Like the suggested IOException. Is it really an IOException? I would probably use ArgumentException, suggested by others here. But just thought I could bring an alternative.
Svish
True. Henk Holterman makes a good point. It is kind of hard to make a suggestion because the question is vague. That is why I try to get the developer to look at existing documentation for guidance.
AMissico
And that is a very good idea. The problem is when you forget that you have alternatives to what exists there. At least I have often found myself trying to use stuff in the framework that hasn't quiiite fit what I needed it to, and tried to sort of twist it into what I need. But then I realize what I am doing, and remember that, hey, why don't I just inherit from something, or from scratch, and make my own thing that would actually be what I want, instead of kiiind of what I want.
Svish
+3  A: 

ArgumentOutOfRangeException - What you're describing is in line with an out of range exception:

The exception that is thrown when the value of an argument is outside the allowable range of values as defined by the invoked method.

ArgumentException is used to validate the characters in the path string not the file type.

The path parameter is a zero-length string, contains only white space, or contains one or more invalid characters.

IMHO the path validation fall-through chart looks like this:

If that's not descriptive enough for you then create your own exception class:

public class InvalidFileTypeException : System.IO.IOException
{
    public InvalidFileTypeException(string path, string acceptedTypeMask) 
    {
        this.Message = string.Format(
            "File type '{0}' does not fall within the expected range: '{1}'", 
            path, 
            acceptedTypeMask);
    }
}

...

throw new InvalidFileTypeException("foo.txt", "*.csv");
xcud
+1, agreed - as the documentation for `ArgumentException` states, "The primary derived classes of `ArgumentException` are `ArgumentNullException` and `ArgumentOutOfRangeException`. These derived classes should be used instead of `ArgumentException`, except in situations where neither of the derived classes is acceptable."
Jeff Sternal