Exceptional exceptions
- 3. Rules
1. All code must compile
2. All exceptions must be thrown because of standard calls to the .Net BCL
3. All improvements must be possible
- 6. 11
12
13
14
var a = Router.GetRoute("A");
var b = Router.GetRoute("B");
var c = Router.GetRoute("C");
var result = new Helper(a.From, b.To, c.ViaProxy).Send();
System.NullReferenceException: Object reference not set to an instance
of an object.
at ExceptionalExamples.UnitTests.NullRef() in UnitTest1.cs: line 14
What is null?
A) a
B) b
C) c
D) I don’t know
- 7. IL_0028: ldloc.1
IL_0029: callvirt instance object ExceptionalExamples.Route::get_To()
Null reference while executing: Route.To
throw new NullReferenceException(
"Null reference while executing: {0}.{1}",
m.ClassName,
m.MethodSignature());
throw new NullReferenceException(“Object reference not set to an instance of an object.”)
Object reference not set to an instance of an object.
- 8. 11
12
13
14
var a = Router.GetRoute("A");
var b = Router.GetRoute("B");
var c = Router.GetRoute("C");
var result = new Helper(a.From, b.To, c.ViaProxy).Send();
System.NullReferenceException:
Null reference while executing: Route.To
at ExceptionalExamples.UnitTests.NullRef() in UnitTest1.cs: line 14
What is null?
A) a
B) b
C) c
D) I don’t know
- 9. This exception proves the rule…
“Print variable values
in your error messages”
…to give the confused coder some guidance
- 11. System.OutOfMemoryException: Out of memory.
at LinearGradientBrush..ctor(Point p1, Point p2, Color c1, Color c2)
at MyForm.OnPaint(PaintEventArgs e) in c:...UnitTest1.cs:line 64
at Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer)
at Control.OnPrint(PaintEventArgs e)
What went wrong?
A) 10,000 rectangles
B) Brush too big
C) Garbage Collection
D) Other
58
59
60
61
62
63
64
65
66
67
for (var i = 0; i < 10000; i++)
{
int w = random.Next(this.Width);
int h = random.Next(this.Height);
var start = new Point(0, 0);
var end = new Point(w, h);
var b = new LinearGradientBrush(start, end, Color.Red, Color.Blue);
var rect = new Rectangle(random.Next(Width), random.Next(Height), w, h);
e.Graphics.FillRectangle(b, rect);
}
- 12. A) new LinearGradientBrush(new Point(0, 0), new Point(w, h), Color.Red, Color.Blue);
B) new LinearGradientBrush(new Rectangle(0, 0, w, h), Color.Red, Color.Blue, 1.0f);
Rectangle '{X=0,Y=0,Width=189,Height=0}' cannot have a width or height equal to 0.
throw new ArgumentException(
@"Rectangle ‘{{X={0},Y={1},Width={2},Height={3}}}'
cannot have a width or height equal to 0.",
start.X, start.Y, end.X - start.X, end.Y - start.Y);
throw new OutOfMemoryException(“Out of memory.”)
Out of memory
- 13. Rectangle '{X=0,Y=0,Width=189,Height=0}' cannot have a width or height
equal to 0.
at LinearGradientBrush..ctor(Point p1, Point p2, Color c1, Color c2)
at MyForm.OnPaint(PaintEventArgs e) in c:...UnitTest1.cs:line 64
at Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer)
at Control.OnPrint(PaintEventArgs e)
What went wrong?
A) 10,000 rectangles
B) Brush too big
C) Garbage Collection
D) Other
58
59
60
61
62
63
64
65
66
67
for (var i = 0; i < 10000; i++)
{
int w = random.Next(this.Width);
int h = random.Next(this.Height);
var start = new Point(0, 0);
var end = new Point(w, h);
var b = new LinearGradientBrush(start, end, Color.Red, Color.Blue);
var rect = new Rectangle(random.Next(Width), random.Next(Height), w, h);
e.Graphics.FillRectangle(b, rect);
}
Height is 0
- 14. This exception proves the rule…
“If the framework gives you bad
exceptions, throw better ones”
…to give the confused coder some guidance
- 15. This exception proves the rule…
“Print other variables to provide context”
…to give the confused coder some guidance
Rectangle '{X=0,Y=0,Width=189,Height=0}'
- 17. System.InvalidCastException: At least one element in the source array could not be cast down
to the destination array type.
at System.Array.Copy(Array s, Array d, Int32 l)
at UnitTests.ArrayCopy() in UnitTest1.cs: line 13
What doesn’t fit?
A) Button
B) Form
C) ToolTip
D) I don’t know
11
12
13
Component[] from = { new Button(), new Form(), new ToolTip(), };
Component[] to = new Collage().GetMemories();
Array.Copy(from, to, from.Length);
- 18. <Form> could not be cast to destination array type <Control[]>
throw new InvalidCastException(
"<{0}> could not be cast to destination array type <{1}>",
element.GetType().Name, to.GetType().Name);
throw new InvalidCastException (“…text…”)
At least one element in the source array could not be cast down to
the destination array type.
Array.Copy(from, to, from.Length);13
- 19. System.InvalidCastException: <Form> could not be cast to destination array type <Control[]>
at System.Array.Copy(Array s, Array d, Int32 l)
at UnitTests.ArrayCopy() in UnitTest1.cs: line 13
What doesn’t fit?
A) Button
B) Form
C) ToolTip
D) I don’t know
11
12
13
Component[] from = { new Button(), new Form(), new ToolTip(), };
Component[] to = new Collage().GetMemories();
Array.Copy(from, to, from.Length);
- 20. This exception proves the rule…
“Runtime details make it clear where the
error comes from”
…to give the confused coder some guidance
- 22. System.FormatException: The string was not recognized as a valid
DateTime. There is an unknown word starting at index 7.
at System.DateTimeParse.Parse(String s, DateTimeFormatInfo dtfi, DateTimeStyles styles)
at System.DateTime.Parse(String s)
at ExceptionalExamples.UnitTests.DateTimeParse() in UnitTest1.cs: line 75
How do you need to sanitize the date?
A) Include CultureInfo
B) Remove “th”
C) Only use first three letters of the month
D) Other
75 var dateTime = DateTime.Parse(form.Date);
- 23. Cannot parse "March 6th 2010“ at index 7
Valid formats include:
"<Month> <Day> <Year>" => “January 14 2010”
"<Month>/<Day>/<Year>" => “1/14/2010”
"<Year>-<Month>-<Day>" => “2010-01-24”
throw new FormatException(@"Cannot parse '{0}' at index {1}
Valid formats include: {2}",
input, 7, tldr);
throw new FormatException (“…text…” + index)
The string was not recognized as a valid DateTime. There is an
unknown word starting at index 7
75 var dateTime = DateTime.Parse(form.Date);
- 25. 75
System.FormatException: Cannot parse "March 6th 2010" at index 7
Valid formats include:
"<Month> <Day> <Year>" => "January 14 2010"
"<Month>/<Day>/<Year>" => "1/14/2010"
"<Year>-<Month>-<Day>" => "2010-01-24"
at System.DateTimeParse.Parse(String s, DateTimeFormatInfo dtfi, DateTimeStyles styles)
at System.DateTime.Parse(String s)
at ExceptionalExamples.UnitTests.DateTimeParse() in UnitTest1.cs: line 75
How do you need to sanitize the date?
A) Include CultureInfo
B) Remove “th”
C) Only us first three letters of the month
D) Other
var dateTime = DateTime.Parse(form.Date);
- 26. This exception proves the rule…
“Show tl;dr examples if
particular formats are required”
…to give the confused coder some guidance
- 28. 82
83
84
85
86
System.MissingMethodException:
Method 'System.Windows.Forms.ButtonBase.GetFlag' not found.
at System.RuntimeType.InvokeMember(String name, BindingFlags bindingFlags, …)
at ExceptionalExamples.UnitTests.ButtonAnimation() in UnitTest1.cs: line 85
What went wrong?
A) Not on ButtonBase
B) Wrong parameters
C) Docs are out of date
D) Other
var su = new SignUpPrompt();
su.Advertise();
var pb = new PrivateObject(su.BuyButton, new PrivateType(typeof(ButtonBase)));
var isAnimating = (bool)pb.Invoke("GetFlag", new[] { 0x0010 });
Assert.IsTrue(isAnimating);
private bool GetFlag(int flag)
- 29. Cannot find method: GetFlag(int[]).
Possible methods starting with “G” are:
GetFlag(int)
GetPreferedSizeCore(Size)
Common Fixes
If method not listed it might be on a base class
i.e. new PrivateObject(o, new PrivateType(typeof(BaseClass)))
If method is listed check your parameter list
i.e. p.Invoke(“MethodName”, param1, param2)
throw new MissingMethodException (“…text…” + method + “…text…”)
Method 'System.Windows.Forms.ButtonBase.GetFlag' not found.
85 var isAnimating = (bool)pb.Invoke("GetFlag", new[] { 0x0010 });
- 31. 82
83
84
85
86
System.MissingMethodException:
Cannot find method: GetFlag(int[]).
Possible methods starting with “G” are:
GetFlag(int)
GetPreferedSizeCore(Size)
Common Fixes
If method not listed it might be on a base class
i.e. new PrivateObject(o, new PrivateType(typeof(BaseClass)))
If method is listed check your parameter list
i.e. p.Invoke(“MethodName”, param1, param2)
at System.RuntimeType.InvokeMember(String name, BindingFlags bindingFlags, …)
at ExceptionalExamples.UnitTests.ButtonAnimation() in UnitTest1.cs: line 85
What went wrong?
A) Not on ButtonBase
B) Wrong parameters
C) Docs are out of date
D) Other
var su = new SignUpPrompt();
su.Advertise();
var pb = new PrivateObject(su.BuyButton, new PrivateType(typeof(ButtonBase)));
var isAnimating = (bool)pb.Invoke("GetFlag", new[] { 0x0010 });
Assert.IsTrue(isAnimating);
- 32. This exception proves the rule…
“Don’t hold back,
You don’t know which clue will help”
…to give the confused coder some guidance
- 33. 82
83
84
85
86
System.MissingMethodException:
Cannot find method: GetFlag(int).
Possible methods starting with “G” are:
<none>
Common Fixes
If method not listed it might be on a base class
i.e. new PrivateObject(o, new PrivateType(typeof(BaseClass)))
If method is listed check your parameter list
i.e. p.Invoke(“MethodName”, param1, param2)
at System.RuntimeType.InvokeMember(String name, BindingFlags bindingFlags, …)
at ExceptionalExamples.UnitTests.ButtonAnimation() in UnitTest1.cs: line 85
What went wrong?
A) Not on Button
B) Wrong parameters
C) Docs are out of date
D) Other
var su = new SignUpPrompt();
su.Advertise();
var pb = new PrivateObject(su.BuyButton);
var isAnimating = (bool)pb.Invoke("GetFlag", 0x0010);
Assert.IsTrue(isAnimating);
- 35. 82
...
100
101
System.DllNotFoundException:
Unable to load DLL 'libsvn_client-1-0.dll':
The specified module could not be found.
(Exception from HRESULT: 0x8007007E)
at ExceptionalExamples.NativeDll.svn_client_info()
at ExceptionalExamples.UnitTests.NativeTest() in UnitTest1.cs: line 82
Why can’t we find the DLL?
A) Wrong File Permissions
B) Wrong Working Directory
C) Wrong Processor Arch
D) Other
NativeDll.svn_client_info();
[DllImport("libsvn_client-1-0.dll")]
public static extern int svn_client_info();
06/25/2014 09:59 PM 10,240 ExceptionalExamples.dll
06/03/2014 06:11 AM 255,849 libsvn_client-1-0.dll
2 File(s) 266,089 bytes
- 36. Problems loading dependencies for
“libsvn_client-1-0.dll”.
Could not find dependency: “MSYS-1.0.dll”
Required libraries:
MSYS-1.0.dll
LIBSVN_DELTA-1-0.DLL
LIBSVN_DIFF-1-0.DLL
LIBAPR-0-0.DLL
LIBSVN_SUBR-1-0.DLL
throw new DllNotFoundException (“…text…” + index)
Unable to load DLL 'libsvn_client-1-0.dll':
The specified module could not be found.
(Exception from HRESULT: 0x8007007E)
100 [DllImport("libsvn_client-1-0.dll")]
- 38. 82
...
100
101
System.DllNotFoundException:
Problems loading dependencies for “libsvn_client-1-0.dll”.
Could not find dependency: “MSYS-1.0.dll”
Required libraries:
MSYS-1.0.dll
LIBSVN_DELTA-1-0.DLL
LIBSVN_DIFF-1-0.DLL
LIBAPR-0-0.DLL
LIBSVN_SUBR-1-0.DLL
at ExceptionalExamples.NativeDll.svn_client_info()
at ExceptionalExamples.UnitTests.NativeTest() in UnitTest1.cs: line 82
Why can’t we find the DLL?
A) Wrong File Permissions
B) Wrong Working Directory
C) Wrong Processor Arch
D) Other
NativeDll.svn_client_info();
[DllImport("libsvn_client-1-0.dll")]
public static extern int svn_client_info();
06/25/2014 09:59 PM 10,240 ExceptionalExamples.dll
06/03/2014 06:11 AM 255,849 libsvn_client-1-0.dll
2 File(s) 266,089 bytes
- 40. Use variable values
Wrap bad exceptions
Provide context
Show runtime details
tl;dr examples
Extra information
Highlight root causes