I've seen this kind of code a lot recently:
try
{
int i = 0;
int x = 0;
Console.WriteLine(i / x);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
This results in the following output:
Attempted to divide by zero.
Unless there's some compelling reason you need an ultra-terse version of the error, it's almost always better to use the provided Exception.ToString() method. Compare the difference:
System.DivideByZeroException: Attempted to divide by zero. at ConsoleApplication1.Program.Main(String[] args) in C:\Program.cs:line 15
This also brings up an interesting corollary: any object you build should have a meaningful .ToString() method. I expect a proper string representation of what you are, not a meaningless echo of your class name!
One object that violates this horribly is DataSet. Let's say we have a DataSet containing a single DataTable. When you type DataSet.ToString(), what do you think should happen? Wait, wait, don't tell me. I'll tell you. This happens:
System.Data.DataSet
Useless. How about something that actually shows the object in string form?
+----------------------------------------------------------------+ | DataSet1 | +----------------------------------------------------------------+ | Table1 | +---------+-----------+------------------+------------+----------+ | field01 | field02 | field03 | field04 | field05 | +---------+-----------+------------------+------------+----------+ | 1 | first | NULL | NULL | NULL | | 2 | second | another | 1999-10-23 | 10:30:00 | | 3 | a third | more foo for you | 1999-10-24 | 10:30:01 | +---------+-----------+------------------+------------+----------+
Seems perfectly logical to me, but you'll have to write your own custom ToString() implementation to get the behavior that should have been there in the first place.
Hear, Hear!
(Clink of beer mugs)
BradC on November 11, 2005 4:31 PMI completely agree, my conservative friend - and I support the liberal use of ascii art in my ToString overrides.
John Kerry on November 11, 2005 8:00 PMAlso, wanted to share what I used on my last campaign for debugging DataSets in VS.NET 2003:
<a href="http://www.visualstudiotips.com/?p=11">http://www.visualstudiotips.com/?p=11</a>
This plug-in offers a great visualization of any xml-serializable type during debugging.
I've tried the ToString() methods you've suggested before, but C#'s Immediate command window doesn't give a pretty representation of newlines, once again making VB.NET the choice of progressives everywhere.
John Kerry on November 11, 2005 8:38 PM> but C#'s Immediate command window doesn't give a pretty representation of newlines,
This drives me crazy! Is there a way to get the C# immediate window to echo \n as a real newline within strings?
Jeff Atwood on November 11, 2005 11:29 PMI agree with the sentiment - it bugs me when <>.toString == <>.Type.ToString. The problem with the DataSet idea is what you do when the underlying object is large. I don't really want a 2GB string returned when I go DataSet.ToString()
Sure, you can tweak it, but I wonder about whether it's even possible to come up with useful guidelines. What sort of metadata to return... DataWareHouse.ToString --> "Zurich DataWareHouse: 43.6TB in 2563 tables, 3.7T rows" beats nothing I suppose.
Of course, the sanity of someone calling ToString on some objects is a little questionable, given what it's normall expected to do.
Moz on November 12, 2005 1:07 AM> Seems perfectly logical to me, but you'll have
> to write your own custom ToString()
> implementation to get the behavior that should
> have been there in the first place.
FWIW, there's an ASCII table generator here:
<a href="http://www.phpguru.org/static/ConsoleTable.html">http://www.phpguru.org/static/ConsoleTable.html</a>
Richard on November 12, 2005 5:17 PMWhen shouldn't you spit out a verbose error message? When you're working on a networked component, like a website or anything that interacts with a database. It's a thousand times easier to find and exploit a SQL injection attack if you get verbose errors. If you tell me where and why your website rejected or crashed on my input, I've learned more about your system and I'm one step closer to cracking it.
If you're shipping it, be terse - "an error occurred, sorry buddy." Don't give your attacker anything useful: you'll slow them down a bit. In fact, do it right - make your catch block call a function that can report terse, report verbose, or log everything possible. That way, if you need to investigate a customer escalation, you can switch em to super verbose diagnostic mode and go from there.
chris on November 13, 2005 12:22 PMAlso - I don't know how much control you have over this blog software, but you should disable the "email address" requirement. Just using this post's comments as an example, of the six unique responders, three used fake email address, two used a blog URL instead of an email address, and only one person used a real one.
chris on November 13, 2005 12:26 PM The problem with the "stack trace" on error is that you end up with the python problem ... where a significant number of errors a user can see end up with 25+ line stack traces instead of "Can't create file: X", "hostname X not found", or "Network connection failed".
This is a problem in general with throwing "exceptions" everywhere, it's often documented very badly what you should be catching where.
"any object you build should have a meaningful .ToString() method"
I have to disagree. Any well structured object system separates the concept of the formatter (ToString) with the data representation (myObject). Any arbitrary ToString() implementation that I may provide is only one of many possibilities, and largely pointless unless I have a specific use in mind.
In addition, by committing early to a specific implementation, I would be making that implementation part of my interface. Thus, I no longer have the freedom to change that implementation to something useful at a later stage.
No thanks, I'll stick with the default implementation.
Steve Campbell on November 14, 2005 2:31 PMI thought I'd point to Ned Batchelder's article on Stringification: http://www.nedbatchelder.com/text/stringification.html
Though he's talking about Java, the same hold true for C# and other languages.
Keith Gaughan on November 16, 2005 12:42 PMI just learned (from playing) that in Managed DirectX, when handling exceptions, .ToString() is your best friend =o)
.Message will always give something like "error in application"
Eber Irigoyen on December 2, 2005 7:55 PMYet another reason to implement .ToString() --
http://blog.slaven.net.au/archives/2007/03/20/always-implement-the-tostring-method/
Jeff Atwood on March 25, 2007 1:56 AMoooo lund .. tum loog choootiye ho aik number ke ..
tumhari ghand main itna bara kira pata nahi gaya kese ... is ke piche bhi koi logic to hogi .. ager mil jay to is e-mail per send keroo please adil_addee@hotmail.com
Jeff,
In the context of the example, don't use ToString(). If you are using Console.Write() or Console.WriteLine(), or string.Format() for that matter, just say:
Console.WriteLine(ex);
Let WriteLine handle calling ToString() for you. ;)
Frisky on February 15, 2008 8:53 AM| Content (c) 2009 Jeff Atwood. Logo image used with permission of the author. (c) 1993 Steven C. McConnell. All Rights Reserved. |