gotham go2014
TRANSCRIPT
There are anima;ons of Nathan and I coming in and out during the story. • Nathan is a friend of mine who contributes to the fsno;fy package, he has done
some great things for the community.
3
• Nathan was online in Slack asking ques;ons about error handling. • So, I did what any friend would do, I jumped into the conversa;on. • AFer talking for a bit he showed me some code similar to this. • When I saw this it just didn’t feel right. • This seemed way to complicated but I couldn’t put my finger on it.
4
• I realized aFer months of coding in Go I had no idea how errors worked. • I saw errors in Go as string messages, there had to be more. • Testament to Go that you don’t need to know all the details. • Bad experience with custom error types in C++ and C# • Custom error types were not prevalent but they did exist in the standard library. • To be effec;ve, let’s learn how errors really work in Go.
** Next Slide – Think About This **
5
• Helps to clarify how to think about errors in Go. • Errors are values, values that need to be handled as errors happen. • Not as an aFer thought or something to be handled later.
11
• A common pa]ern in Go. • The error value returned is checked against the value of nil. • If the error value is not nil, then an error occurred and all other values are ignored. • The error is handled immediately and decisions are made as to how to proceed.
** Next Slide – Standard Library Support **
12
• The error interface as declared by the standard library. • Contains a single method called Error that returns a string. • The interface is built into the language. • Though it is unexported by its name, we s;ll have access to it.
14
• Default implementa;on of the error interface. • errorString is declared in the errors package. • Unexported struct with a single unexported field. • The implementa;on uses a pointer receiver and returns the value of s. • Most used concrete type in the standard library for error values. • The nature of interfaces make this struct very effec;ve in handling errors.
15
• Use New func to create error values using the struct as the concrete type. • Takes a string and returns a pointer of type errorString. • The return type for the New func;on is an interface value of type error. • We return a pointer of type errorString. • The caller receives is an interface value of type error. • What does the value that the caller receives actually looks like?
16
• Interface value is always a two machine word value. • It stores a concrete type value that implements the interface. • When the New func;on is an error interface value is created on the return and the
errorString pointer is stored within it. • The language support abstracts this implementa;on away and makes working with
these values intui;ve.
17
• Just as a note. • This is the value that is actually returned for nil. • An interface value is always returned. • We have like types present on both sides of the compare statement.
18
• Second way to create an error interface value based on the errorString struct. • Use when you need a forma]ed error, usually with local variables. • No;ce the use of the New func;on from the errors package.
** Next – Use In Standard Library **
19
• Let’s learn a technique used in the standard library to help us iden;ty specific errors.
• The error interface variables above are declared in the bufio package. • They provide support for iden;fying specific errors. • This works when the error messages are sta;c.
21
• How to use the error interface variables to iden;fy which error was returned by the Peek func;on.
• The Peek func;on can return either the ErrNega;veCount or ErrBufferFull error variable.
• We use the same variables to iden;fy the specific error returned. • Make a more informed error handling decision.
22
• How to use the error interface variables to iden;fy which error was returned by the Peek func;on.
• The Peek func;on can return either the ErrNega;veCount or ErrBufferFull error variable.
• We use the same variables to iden;fy the specific error returned. • Make a more informed error handling decision.
23
• Other packages like the io package use the same technique • I am sure you have compared the returned error interface value to EOF.
24
• Here is the implementa;on of the ReadAtLeast func;on from the io package. • We see how these variables are being returned • We see how the EOF variable is used internally to check for that error. • When you need to make a decision about a specific error, check if an error
interface variable exists to help you. ** Next – Custom Error Types **
25
• How to use the error interface variables to iden;fy which error was returned by the Peek func;on.
• The Peek func;on can return either the ErrNega;veCount or ErrBufferFull error variable.
• We use the same variables to iden;fy the specific error returned. • Make a more informed error handling decision.
• This is a custom error type implemented within the net package. • The name of the custom error type follows the Go naming conven;on for custom
error types. • The custom error type should provide context associated with the error to help
the caller make a more informed decision. • The first three fields provide context about the network opera;on being
performed when an error occurs. • The fourth field contains the actual error that occurred. • The custom error type exists to provide the context associated with the error.
29
• This is the implementa;on of the error interface for OpError. • The context associated with the error is used to produce a more detailed error
message. • The context enhances the details and produces an error message with more
meaning.
30
• This is a custom error type implemented in the json package. • This custom error type is used to report errors that occur when a value can’t be
decoded into a specific Go type. • In this case, the type itself provides the context and maintains state associated
with the error.
31
• The implementa;on of the error interface takes the state associated with the error and produces a detailed and context rich message.
32
• This custom error type is used to report when there are invalid arguments passed into an unmarshal call.
• In this case, only the type informa;on associated with the bad argument is required to be stored.
33
• Here we see the implementa;on of the error interface for this custom error type. • Again the state associated with the error is used to produce an error message with
more meaning and context.
34
In these cases • A custom error type provided context beyond what the errors package
could provide. • The context helped the caller make a more informed decision about the
error ** Next – Concrete Type Iden;fica;on **
35
• This method is called by the exported Unmarshal func;on. • Method has the poten;al to return error values of different concrete types. • Pointers of type UnmarshalTypeError, InvalidUnmarshalError or errorString. • Each error contains a different context that is important to know. • We want to make an informed decision on how to handle the specific error.
37
• Iden;fy the concrete type is for the stored value inside the error interface value. • You can do this, but there is a be]er way.
38
• The switch statement supports this special syntax. • An interface type conversion using the keyword type. • Declare case statements based on the different concrete types we want to check
for.
39
• Introduce yourself • I realized aFer months of coding in Go I had no idea how errors worked. • I saw errors in Go as string messages, there had to be more. • Testament to Go that you don’t need to know all the details. • Bad experience with custom error types in C++ and C# • Custom error types were not prevalent but they did exist in the standard library. • To be effec;ve, let’s learn how errors really work in Go.
43