Click here to Skip to main content
15,358,470 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
   
Comments
Shahin Khorshidnia 11-Jul-12 0:03am
   
Good points
+5
   
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
cass3000 11-Jul-12 16:55pm
   
Thanks for your answers Sergey. This class library will be used into a bigger system, so, in the client app, I want to log all the possible information when a exception occurs.

Maybe you already answered this but, it is my first approach (having a try-catch block for each field) a good and efficient way to achieve what I need (log specific information about an exception)?

Second, with you being the author of a complete structured exception handling mechanism, don't you have information about it that you can share?
Sergey Alexandrovich Kryukov 25-Jul-12 15:07pm
   
You are very welcome. The information I can possibly share would be about the usage of existing structured exception handling systems. The system I developed was a stand-along library written in inline assembly combined with high-level OOP language (Borland Pascal) for 8086/8088 CPUs and was a part of my bigger library introducing object-oriented threading (when it was not yet introduced in Linux, for example). This code can hardly be applicable to any modern systems, so the value of it is mainly understanding the principles in depth, starting from the CPU level, which is also very different for IA-32, IA-64 and x86-64 instruction-set architectures which makes both threading and exception handling implementation way simpler and of much better performance. This knowledge helps to understand best practices in using those technologies.
--SA
cass3000 26-Jul-12 9:27am
   
Thanks Sergey, what you comment sounds very very interesting. I hope you can share the info about the usage of existing structured exception handling systems.

Do you have a blog or webpage where to read about your developments?
Sergey Alexandrovich Kryukov 27-Jul-12 17:00pm
   
I do have a Web site you can see from my profile (or type my full name with any search engine -- most of them will return my site in first line), but -- not much about my developments...
--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.
   
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.
   
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