Click here to Skip to main content
15,867,308 members
Please Sign up or sign in to vote.
4.67/5 (3 votes)
See more:
I'm writing a class that has a function which receives a comma separated string, split the string, parse the values and finally returns a new filled class with these values.

Since the class is part of a class library, i wish to know which is the best way of throwing exceptions to the final users of my class.

I was thinking to throw an exception for each malformed field to provide helpful messages about where is the problem, something like this:

VB
Function FromString(ByVal fields As String) As FilledClass
   Dim aFields() AS String
   aFields = fields.Split(","c)

   Dim newClass AS New FilledClass()

   Try
      newClass.Field1 = Double.Parse(aFields(0))
   Catch ex AS Exception
      Throw New FormatException("Invalid string: field 1", ex)
   End Try

   Try
      newClass.Field2 = Integer.Parse(aFields(1))
   Catch ex AS Exception
      Throw New FormatException("Invalid string: field 2", ex)
   End Try

   Try
      newClass.Field3 = Byte.Parse(aFields(2))
   Catch ex AS Exception
      Throw New FormatException("Invalid string: field 3", ex)
   End Try

   Return newClass
End Function


Is this a good approach? or it is better throw only one general exception?

VB
Function FromString(ByVal fields As String) As FilledClass
   Dim aFields() AS String
   aFields = fields.Split(","c)

   Dim newClass AS New FilledClass()

   Try
      newClass.Field1 = Double.Parse(aFields(0))
      newClass.Field2 = Integer.Parse(aFields(1))
      newClass.Field3 = Byte.Parse(aFields(2))
   Catch ex AS Exception
      Throw New FormatException("Invalid string", ex)
   End Try

   Return newClass
End Function


Is there a guideline for this or a best practice to do this?
Posted
Comments
Sergey Alexandrovich Kryukov 10-Jul-12 19:16pm    
Generally, I like the approaches where an exception is thrown, my 5 for the question.
--SA

Generally, I like the approaches where an exception is thrown. Re-throwing of the exception is also a good thing. Here you follow the exception-based "throw-and-forget" approach. So, I do not fully agree with Naerling: using TryParse is not always the best thing. Besides, as the name suggests, this TryParse could be implemented using try-catch block. (As far as I remember the real .NET source code I saw, this is not the case, in fact.) So, you could always write your own "TryParse", with additional options. Anyway, blocking the propagation of an exception is a bad thing, defeating the purpose of exception mechanism.

The problem is that the information on which exactly field causes the problem is lost. This is bad because otherwise you could, say, focus a edit box where there is a problem. The approach here is this: it depends on how much detail would you really need from the exception handler. You could do it in a more or less fine-grain fashion, but again, using exceptions gives you more freedom. If you put all exceptions together, it gives you less room for development bugs and requires less code. You decide what exactly you need in each case.

—SA
 
Share this answer
 
Comments
Shahin Khorshidnia 11-Jul-12 0:03am    
Good points
+5
Sergey Alexandrovich Kryukov 11-Jul-12 0:13am    
Thank you, Shahin.
--SA
cass3000 11-Jul-12 9:37am    
Thank you Sergey. What exactly do you mean with "put all exceptions together"?,
and as says Clifford, it is very costly my first approach?
Sergey Alexandrovich Kryukov 11-Jul-12 14:25pm    
I mean this:

You see, you throw exceptions many times as the execution goes down the stack (and this is a run-time matter, can be different in any run-time), and catch all of them in only one place per thread (plus maybe very few catches to cover some very special cases, such as parsing errors). This is exactly how isolation and separation of concerns if achieved.

If you have more questions, feel free to ask. (I'm the author of the implementation of a VERY early fully-fledged and complete structured exception handling mechanism: at that time, it was already available in CLU and Ada, but not yet introduced in C++, so I know quite a bit on how it works.) If not, please consider accepting this answer formally (green button) -- thanks.
--SA
Sergey Alexandrovich Kryukov 11-Jul-12 14:27pm    
Now, how costly? A brief answer is: it is very, very efficient. For concrete cases, time it by yourself, using System.Diagnostic.Stopwatch (see).
--SA
Better would be to simply use a method that takes a Double, Integer and Byte. Assuming you don't want that (for whatever reason you have) you should not use Parse[^] and wait for an Exception to be thrown. Better would be to use TryParse[^] instead. It returns a Boolean which lets you know wether the String could be parsed or not, in which case you can take appropriate action.
Furthermore you could throw a detailed Exception, such as "Invalid String: Field 3", but debugging the input of the function is not very hard I would say. Calling a function such as this requires full knowledge of the internals of your function. As such the user would already know the function requires a String in format "####0.####, ######0, ##0" (well, sort of). Finding that it doesn't meet the requirement is easy enough and mentioning which field it is in your Exception adds little value.
 
Share this answer
 
v2
Comments
cass3000 10-Jul-12 18:09pm    
Well, the code is just a little example, not the real one, the real one parses GPS sentences into objects. There is a base abstract class and there are a specific derived class for each kind of sentence each one with its own implementation of the "FromString" function.
Sander Rossel 10-Jul-12 19:08pm    
That doesn't really change anything I've said :)
Anyway, an Exception that has a lot of detail always comes in handy ("Object not set to an instance of an Object"... WHAT OBJECT!?!?!?).
In this case you should wonder why thing could go wrong though. For example, if the String only contains numerics little could go wrong. You can throw an Exception saying "Invalid string. String contains non-numeric characters". That will be enough for most developers. If each of the elements needs a very specific format like (1st element) a hash sign, 5 numerics, a pipe (|), another numeric and a letter (just to name something weird) a more detailed Exception message would definitly help the programmer using your class.
Sander Rossel 10-Jul-12 19:12pm    
By the way, it's less obvious, and you shouldn't rely on it, but I've tracked down numerous bugs by looking at the StackTrace of an Exception. For example:
at ParseField2(String)
at ParseFields(String())
at FromString(String)
The StackTrace clearly shows the Exception was thrown when trying to Parse field 2. This should be the result of good coding practices rather than a goal for debugging purposes though :)
First of all, exceptions are costly, so you don't want to throw them multiple time. What I would suggest is that you collect all the issues in the exception, create a class that can contain this infomration that is derived from exception. You will probably want a specific exception for this issue anyway. Then you can catch this specific excpetion, and it will have all the information about the issue. Since you are creating an exception class for this exception anyway, you can have a collection of issues in the class.
 
Share this answer
 
Comments
cass3000 11-Jul-12 9:22am    
I don´t know how costly is this, because only the first exception that occurs will be thrown. In fact, thinking on that, maybe is a good approach throw a general exception with all the issues.
Clifford Nelson 11-Jul-12 13:50pm    
Basically what I was recommending, but probably want to throw a specific exception so that the problem can be more clearly determined

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900