<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Wesley Powell</title>
    <description>The latest articles on DEV Community by Wesley Powell (@wspowell).</description>
    <link>https://dev.to/wspowell</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F893971%2F61f9df49-31e2-4683-be81-5bb17313103e.jpeg</url>
      <title>DEV Community: Wesley Powell</title>
      <link>https://dev.to/wspowell</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/wspowell"/>
    <language>en</language>
    <item>
      <title>New Golang Error: Final Update</title>
      <dc:creator>Wesley Powell</dc:creator>
      <pubDate>Fri, 21 Jul 2023 00:23:01 +0000</pubDate>
      <link>https://dev.to/wspowell/new-golang-error-final-update-12ef</link>
      <guid>https://dev.to/wspowell/new-golang-error-final-update-12ef</guid>
      <description>&lt;p&gt;It has been a while since I last posted about better golang error handling and I thought I would follow up with how this ended up in real code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Error Design
&lt;/h2&gt;

&lt;p&gt;The design is largely the same now, but with some naming tweaks and extra functions. I have also ironed out a lot of details regarding error propagation and added some more interesting concepts.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type Cause interface {
    ~uint
}

type Error[T Cause] struct {
    Cause     T
    rootCause any
    Message   string
    // Add as much extra detail as you wish!
}

func NewError[T Cause](ctx context.Context, cause T, message string, values ...any) Error[T] {
    // ...
}

func FromError[T Cause, R Cause](cause T, origin Error[R]) Error[T] {
    // ...
}

func Ok[T Cause]() Error[T] {
    return Error[T]{}
}

// Error message.
//
// Satisfies the error interface.
func (self Error[T]) Error() string {
    return self.String()
}

func (self Error[T]) IsOk() bool {
    return self.Cause == 0
}

func (self Error[T]) IsErr() bool {
    return self.Cause != 0
}

func (self Error[T]) String() string {
    // ...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that the &lt;code&gt;Error&lt;/code&gt; is now simply the &lt;em&gt;transport mechanism&lt;/em&gt; for the important piece, the &lt;code&gt;Cause&lt;/code&gt;. When handling the &lt;code&gt;Error&lt;/code&gt;, we check its &lt;code&gt;Cause&lt;/code&gt; to see what &lt;em&gt;caused&lt;/em&gt; the function to fail.&lt;/p&gt;

&lt;p&gt;When propagating errors, there is now the &lt;code&gt;FromError()&lt;/code&gt; option. This allows you to simply take an error from a function and return it as another error for your function. Note that this is just copying data around and there is no linked list behind the scenes. I did find it useful to keep the &lt;code&gt;rootCause&lt;/code&gt; as well as the current &lt;code&gt;Cause&lt;/code&gt;. That is so that we can log the first &lt;code&gt;Cause&lt;/code&gt; while still being able to react to different &lt;code&gt;Cause&lt;/code&gt;s as we pass the error up the call stack. &lt;/p&gt;

&lt;p&gt;One of the nicest benefits of &lt;code&gt;Error&lt;/code&gt; over golang's error is that it requires zero heap allocation. As defined above, &lt;code&gt;Error&lt;/code&gt; is &lt;em&gt;clearly&lt;/em&gt; superior to golang's error in every way. It does exactly what golang can do, but for a fraction of the CPU time and memory allocation. I encourage you to benchmark it yourself.&lt;/p&gt;

&lt;p&gt;Note that you can add anything you wish to the &lt;code&gt;Error&lt;/code&gt;. It is simply there as metadata for your root cause. If you wish to make your errors heavier, but more descriptive, you could add codes, stack traces, metrics, logging, and more. There is a lot of power you can wield in this simple structure. This is simply a starting point for your project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Error Usage
&lt;/h2&gt;

&lt;p&gt;Here is an example of it being used.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type MyError uint

const (
    MyErrorInternalFailure = MyError(iota + 1)
    MyErrorNotFound
)

func getThing(ctx context.Context) Error[MyError] {
    if true {
        return NewError(ctx, MyErrorNotFound, "could not find the thing")
    }
    return errors.Ok[MyError]()
}

func main() {
    ctx := context.Background()

    switch getThingErr := getThing(ctx); getThingErr.Cause {
    case MyErrorInternalFailure:
        fmt.Println("failed finding the thing, internal failure: " + getThingErr.Error())
    case MyErrorNotFound:
        fmt.Println("failed finding the thing, not found: " + getThingErr.Error())
    default:
        // Found the thing!
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When thinking about what error causes to create, think about what is important to test. Each failure case should have its own &lt;code&gt;Cause&lt;/code&gt; enum value on the function. For example, a function may return &lt;code&gt;NotFound&lt;/code&gt;, &lt;code&gt;InternalFailure&lt;/code&gt;, &lt;code&gt;BadRequest&lt;/code&gt;, etc. This means you can easily test for different cases. I find that keeping your testing in mind helps guide your coding decisions.&lt;/p&gt;

&lt;p&gt;When a consumer handles a &lt;code&gt;NotFound&lt;/code&gt; case, it may not care and totally ignore it or it may combine it with another error that the function returns. Regrouping error causes becomes useful in cases where say your storage layer has a bunch of storage specific error cases, like maybe MySqlTransactionFailure, but the calling function just lumps them all into a generic &lt;code&gt;InternalFailure&lt;/code&gt; cause that it returns.&lt;/p&gt;

&lt;p&gt;Another important point for this pattern is that you only ever have two return values: &lt;code&gt;(&amp;lt;value&amp;gt;, &amp;lt;error&amp;gt;)&lt;/code&gt;. Any "soft" error where your value may not exist should be contained inside your error cause enumeration. That eliminates the awkward case where you have no value, but no error either and you get the dreaded (in golang errors) &lt;code&gt;(nil, nil)&lt;/code&gt;, and you have to determine what that actually means. Keeping this you-have-it-or-not approach ensures that your error &lt;code&gt;switch&lt;/code&gt;s always handle &lt;em&gt;every&lt;/em&gt; possible case and that your &lt;code&gt;default&lt;/code&gt; case is purely reserved for your success case and you are guaranteed a value.&lt;/p&gt;

&lt;p&gt;A nice side effect of the switch pattern, is that you can often keep your variables with the scope of the switch to avoid mistakenly referencing variables and to keep your code cleaner.&lt;/p&gt;

&lt;p&gt;Knowing that you are guaranteed a value and guaranteed those specific failure causes becomes powerful within large applications. When you enable linting (which you should already have!), any new error enum value will highlight your code where you need to handle this new case. When you remove a case, you will get compile errors showing where that case is no longer valid. This makes making business logic changes to large existing applications becomes much easier because your code highlights everything you need to change. It also forces you to think about the new case. Let's say you add a &lt;code&gt;UserNotFound&lt;/code&gt; case to a function deep inside your application. If you were using golang errors, then you may add this case and think you have it handled because everything is &lt;code&gt;error&lt;/code&gt; and checked with &lt;code&gt;if err != nil&lt;/code&gt;. But because each function is typed to its own possible error causes, you are now forced to handle this case in your entire application. This helps eliminate bugs before they even exist! I can attest that I have been pleasantly surprised at how many times this error pattern has saved me from making logical mistakes.&lt;/p&gt;

&lt;p&gt;I encourage you to use this sample code and expand on it in your applications for your own needs. Check out the full example on the &lt;a href="https://go.dev/play/p/pqYLLdlNjbJ"&gt;Go Playground&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>go</category>
      <category>design</category>
      <category>errors</category>
      <category>programming</category>
    </item>
    <item>
      <title>Avoid go1.20 Error Handling</title>
      <dc:creator>Wesley Powell</dc:creator>
      <pubDate>Mon, 06 Feb 2023 06:39:27 +0000</pubDate>
      <link>https://dev.to/wspowell/avoid-go120-error-handling-27hd</link>
      <guid>https://dev.to/wspowell/avoid-go120-error-handling-27hd</guid>
      <description>&lt;p&gt;I have already stated just how bad golang error handling is in  &lt;a href="https://dev.to/wspowell/series/19707"&gt;Golang Error Handling&lt;/a&gt;. This post focuses on the new additions to error handling in go1.20.&lt;/p&gt;

&lt;h2&gt;
  
  
  My hot take
&lt;/h2&gt;

&lt;p&gt;My opinion remains that error handling provided by golang is not great, but I believe that the new go1.20 additions bring a whole new dimension of issues to the language that are just &lt;em&gt;staggering&lt;/em&gt;. To put it bluntly, I have never seen a feature released by a language that actively makes the language &lt;em&gt;worse&lt;/em&gt;. This and other bizarre decisions make me deeply concerned for the future of golang. If I ever see &lt;code&gt;errors.Join()&lt;/code&gt; or &lt;code&gt;Unwrap() []error&lt;/code&gt; in a code review, it will not get my approval. &lt;/p&gt;

&lt;h2&gt;
  
  
  Pre-go1.20
&lt;/h2&gt;

&lt;p&gt;Let me show an example of the pre-go1.20 state of things just to emphasize the absurdity of these new changes. &lt;code&gt;error&lt;/code&gt; is a linked list of any implementation, unknown to the consumer, that just has to satisfy &lt;code&gt;Error() string&lt;/code&gt;. Let's take a look at what this would look like if we did not have a nice &lt;code&gt;error&lt;/code&gt; word saving face.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Go Playground: https://go.dev/play/p/f3Xwyv30C4U
type LinkedList struct {
    value any
    next  *LinkedList
}

func New(value any) *LinkedList {
    return &amp;amp;LinkedList{
        value: value,
        next:  nil,
    }
}

func Wrap(value any, currentList *LinkedList) *LinkedList {
    return &amp;amp;LinkedList{
        value: value,
        next:  currentList,
    }
}

func DoWork() *LinkedList {
    if resultLinkedList := addJob(); resultLinkedList != nil {
        return Wrap("DoWork failed", resultLinkedList)
    }

    return nil
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is effectively what is happening when you create errors and wrap them in golang. Note: I omitted the linked list traversal. I would be very concerned if someone tried to implement this error pattern in any language. It is complex, error prone, and an anti-pattern. It also leaks implementation details. Any consumer of &lt;code&gt;DoWork()&lt;/code&gt; must also know what &lt;code&gt;addJob()&lt;/code&gt; does and what its error returns mean. To say otherwise is to ignore the very nature of the linked list. This is not great in itself, but it gets even worse with go1.20.&lt;/p&gt;

&lt;h2&gt;
  
  
  Enter go1.20
&lt;/h2&gt;

&lt;p&gt;This update introduces two new additions to the &lt;code&gt;errors&lt;/code&gt; package:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;errors.Join()&lt;/li&gt;
&lt;li&gt;Unwrap() []error&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This means that we can now specify multiple errors when wrapping. For example: &lt;code&gt;fmt.Errorf("errors: %w, %w", err1, err2)&lt;/code&gt;. If you notice, this also means that we now have to track multiple errors instead of just one per error instance, which means we have moved from a linked list to a tree of errors. Size and time complexity just increased. Think about the &lt;code&gt;LinkedList&lt;/code&gt; example above and how that would become even more complicated.&lt;/p&gt;

&lt;p&gt;So what does this even look like in go1.20. Here is a small example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Go Playground: https://go.dev/play/p/-iUZt7kSp6-
func externalFn1() error {
    return fmt.Errorf("%w OR %w?", err1, err2)
}

func externalFn2() error {
    return fmt.Errorf("%w OR %w?", err2, err1)
}

func printErr(err error) {
    switch {
    case errors.Is(err, err1):
        fmt.Println("err is err1 - " + err.Error())
    case errors.Is(err, err2):
        fmt.Println("err is err2 - " + err.Error())
    }
}

// printErr(externalFn1())
// prints -&amp;gt; err is err1 - one OR two?
// printErr(externalFn2())
// prints -&amp;gt; err is err1 - two OR one?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This highlights a massive issue with this: the error is both err1 and err2. However, when you check for those, you will never fall into the err2 case because err1 matches first. &lt;/p&gt;

&lt;p&gt;Because a function can now return &lt;em&gt;multiple&lt;/em&gt; errors, there is no way to determine what the &lt;em&gt;actual&lt;/em&gt; error is. How should a developer handle these errors? Maybe one function only has one error but there is the possibility that it could be more than one, so all error handling must account for that case. Maybe one function returns two errors that are meant to be handled in conjunction, like a http status code and the error that caused it, and another function returns multiple errors but certain ones should be handled over overs. There is just no way of knowing without having to read documentation for each function and understand its internal behavior. At that point, what you have is no longer error handling, but a full blown application with business logic, documentation, and various use cases. This is not what we need from our error handling.&lt;/p&gt;

&lt;p&gt;One aspect that may not be immediately apparent is that due to golang's rule that functions may not be overloaded, an error type cannot implement both &lt;code&gt;Unwrap() error&lt;/code&gt; and &lt;code&gt;Unwrap() []error&lt;/code&gt;. That means that if you have a mix of LinkedList errors and Tree errors you are bound to run into trouble. The error type can only implement one version of that function, so any code out there that type asserts for &lt;code&gt;Unwrap() error&lt;/code&gt; must now be updated to handle both cases. &lt;/p&gt;

&lt;p&gt;To demonstrate this issue, look at the following example and observe that the result of unwrapping the error is &lt;code&gt;nil&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Go Playground: https://go.dev/play/p/0gVlavnmvJf
err := fmt.Errorf("this is bad: %w, %w", err1, err2)
unwrappedErr := errors.Unwrap(err)
fmt.Println(unwrappedErr) // prints &amp;lt;nil&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As compared to the same code but only wrapping one error.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Go Playground: https://go.dev/play/p/0gVlavnmvJf
err := fmt.Errorf("this is bad: %w", err1)
unwrappedErr := errors.Unwrap(err)
fmt.Println(unwrappedErr) // prints one
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When it comes to performance, it just gets worse. We have no ordering to the error tree here, so we still have O(n) at worse case search. Plus, all of the issues that plagued LinkedList errors still plague Tree errors but now the complexities just increased.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion and Further Reading
&lt;/h2&gt;

&lt;p&gt;In short, stop. Just do not do it. I guarantee that I have not covered all issues related to Tree errors. There is some great feedback on this approach in various other threads, &lt;a href="https://www.reddit.com/r/golang/comments/z870te/comment/iyg2o51/?utm_source=share&amp;amp;utm_medium=web2x&amp;amp;context=3" rel="noopener noreferrer"&gt;like this one&lt;/a&gt;. Reading through &lt;a href="https://github.com/golang/go/issues/53435" rel="noopener noreferrer"&gt;the actual proposal thread&lt;/a&gt; for this feature illuminates other issues that I had not even considered yet, like thread safety. &lt;/p&gt;

&lt;p&gt;For a straightforward, unbiased post, &lt;a href="https://lukas.zapletalovi.com/posts/2022/wrapping-multiple-errors/" rel="noopener noreferrer"&gt;this blog post&lt;/a&gt; explains the new mechanics well. &lt;/p&gt;

&lt;p&gt;In my personal opinion, after having actually removed &lt;code&gt;error&lt;/code&gt; from an entire application now, we are all better off ignoring &lt;code&gt;error&lt;/code&gt; completely along with all changes added to errors in go1.20.&lt;/p&gt;

</description>
      <category>frontend</category>
      <category>javascript</category>
      <category>react</category>
      <category>gsap</category>
    </item>
    <item>
      <title>Follow Up: Establishing A Better Pattern</title>
      <dc:creator>Wesley Powell</dc:creator>
      <pubDate>Fri, 09 Sep 2022 00:24:31 +0000</pubDate>
      <link>https://dev.to/wspowell/follow-up-establishing-a-better-pattern-33b6</link>
      <guid>https://dev.to/wspowell/follow-up-establishing-a-better-pattern-33b6</guid>
      <description>&lt;h2&gt;
  
  
  &lt;em&gt;Takeaways&lt;/em&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Errors as uint64 for better performance&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Use enums to define error cases&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;By convention, 0 is "OK" or "no error"&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Use the &lt;a href="https://golangci-lint.run/usage/linters/#exhaustive"&gt;exhaustive linter&lt;/a&gt; with &lt;code&gt;switch&lt;/code&gt;&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Implement &lt;a href="https://cs.opensource.google/go/go/+/refs/tags/go1.19.1:src/fmt/print.go;l=62"&gt;Stringer&lt;/a&gt; on enums for human readable error messages&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Use generic &lt;code&gt;T ~uint64&lt;/code&gt; to type custom structs to errors&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I have been racking my brain trying to figure out a better golang error handling pattern. In my previous posts, I alluded to a potential solution but after some experimentation it was not sufficient. After revisiting and coming back to this topic a few more times, I think I hit on something. The best part is this requires no external dependencies and does not require wholesale conversions to this new pattern.&lt;/p&gt;

&lt;h2&gt;
  
  
  Defining an Error
&lt;/h2&gt;

&lt;p&gt;Defining what an error is actually gets us to the root of the issue. Usually in golang, an error is a string or a struct that contains a string value. But when something fails in a function, sometimes there really is no reason to return a full human readable string. It can be just as good to return an integer constant that identifies the error.&lt;/p&gt;

&lt;h3&gt;
  
  
  Performance
&lt;/h3&gt;

&lt;p&gt;Why an integer, though? If we examine &lt;code&gt;error&lt;/code&gt;, we can see that it is an interface and therefore using it will cause the value to escape to the heap. That means all &lt;code&gt;errors&lt;/code&gt; are heap allocations. While golang utilizes garbage collection, too many heap allocations can cause performance issues across your application. Consider a situation where an application is running nominally and suddenly an influx of errors occur. You would not want a spike in error value allocations to cause an unexpected CPU spike that could potentially ripple through a system. Defining errors as &lt;code&gt;uint64&lt;/code&gt; solves that problem. That will be heap allocation free.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Takeaway: Errors as uint64 for better performance&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Case study: context.Context
&lt;/h2&gt;

&lt;p&gt;Let us take &lt;code&gt;Err() error&lt;/code&gt; from &lt;a href="https://pkg.go.dev/context#Context"&gt;&lt;code&gt;context.Context&lt;/code&gt;&lt;/a&gt; as an example. In the function comments, it essentially states that it returns one of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No error (&lt;code&gt;nil&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;var Canceled = errors.New("context canceled")&lt;/li&gt;
&lt;li&gt;var DeadlineExceeded error = deadlineExceededError{}&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We can already take that description and use it directly in our first new error pattern example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type ContextError uint64

const (
    Ok ContextError = iota
    Canceled 
    DeadlineExceeded
)

func (c Context) Err() ContextError {
    // Could return this error denoting the Context was canceled.
    return Canceled
    // Or this error denoting the Context deadline passed.
    return DeadlineExceeded
    // Or there is no error.
    return Ok
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Right away we can see that provides self-documenting code. We know &lt;code&gt;Err()&lt;/code&gt; will return a &lt;code&gt;ContextError&lt;/code&gt; and that it is defined as one of two values: &lt;code&gt;Ok&lt;/code&gt;, &lt;code&gt;Canceled&lt;/code&gt;, &lt;code&gt;DeadlineExceeded&lt;/code&gt;. This is a huge win already.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Takeaway: Use enums to define error cases&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;How would we use this? Before, we would use &lt;code&gt;if err != nil&lt;/code&gt; or possibly &lt;code&gt;if errors.Is(err, context.Canceled)&lt;/code&gt;. Instead, we can stick to one single pattern using &lt;code&gt;switch&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;switch err := ctx.Err(); err {
case context.Canceled:
    // Handle the case when the Context is canceled.
case context.DeadlineExceeded:
    // Handle the case when the Context deadline has passed.
case context.Ok:
    // There is no error!
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let us take a look at what happens here. The &lt;code&gt;switch&lt;/code&gt; here acts like a better &lt;code&gt;if-else&lt;/code&gt;. We invoke &lt;code&gt;Err()&lt;/code&gt; and get an &lt;code&gt;err&lt;/code&gt; value and then we switch on &lt;code&gt;err&lt;/code&gt; to find the correct case. If there is no error then we just return &lt;code&gt;Ok&lt;/code&gt; (which is just 0). Since the type of &lt;code&gt;err&lt;/code&gt; is &lt;code&gt;ContextError&lt;/code&gt;, we know exactly what errors to handle!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Takeaway: By convention, 0 is "OK" or "no error"&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In fact, if you are using the highly recommended linting tool &lt;a href="https://golangci-lint.run/"&gt;golangci-lint&lt;/a&gt; with the &lt;a href="https://golangci-lint.run/usage/linters/#exhaustive"&gt;exhaustive linter&lt;/a&gt; enabled then your IDE will actually warn you when you are missing an error case. And if an error value is ever removed, then you will get a compile error telling you that case is no longer valid. The usage of this pattern is heavily influenced by rust's &lt;a href="https://doc.rust-lang.org/rust-by-example/flow_control/match/destructuring/destructure_enum.html"&gt;&lt;code&gt;match&lt;/code&gt;&lt;/a&gt; operator.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Takeaway: Use the &lt;code&gt;exhaustive&lt;/code&gt; linter with &lt;code&gt;switch&lt;/code&gt;&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Static Error Messages
&lt;/h3&gt;

&lt;p&gt;Sometimes we want to log our errors and &lt;code&gt;uint64&lt;/code&gt; will not cut it. Especially since &lt;code&gt;iota&lt;/code&gt; starts over for each &lt;code&gt;const&lt;/code&gt; block. Fortunately, golang has already solved this for us as well! Whenever you invoke a &lt;code&gt;Print&lt;/code&gt; on a value via &lt;code&gt;fmt.Println()&lt;/code&gt;, the &lt;code&gt;log&lt;/code&gt; package, or other method, it will attempt to print it based on reflection. There is actually a &lt;code&gt;Stringer&lt;/code&gt; interface that &lt;a href="https://cs.opensource.google/go/go/+/refs/tags/go1.19.1:src/fmt/print.go;l=654"&gt;golang will check for&lt;/a&gt; and use that if the value implements it. This interface looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Stringer is implemented by any value that has a String method,
// which defines the “native” format for that value.
// The String method is used to print values passed as an operand
// to any format that accepts a string or to an unformatted printer
// such as Print.
type Stringer interface {
    String() string
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using this on an enum is &lt;a href="https://stackoverflow.com/a/62291060"&gt;already an established pattern&lt;/a&gt;. We can easily attach this to our &lt;code&gt;ContextError&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func (self ContextError) String() string {
    return [...]string{
        "ok",
        "context canceled",
        "context deadline exceeded",
    }[self]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Takeaway: Implement Stringer on enums for human readable error messages&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Custom Errors
&lt;/h2&gt;

&lt;p&gt;Sometimes we do want to return some context with our errors. In those instances, a &lt;code&gt;uint64&lt;/code&gt; will not cut it. For those cases we can simply create custom error structs that suite our needs. For example, if all we need is a dynamic string to accompany our &lt;code&gt;uint64&lt;/code&gt; error for log printing later, we can do something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// errors/message.go
type Message[T ~uint64] struct {
    Error   T
    Message string
}

func NewMessage[T ~uint64](err T, message string) Message[T] {
    return Message[T]{
        Error:   err,
        Message: message,
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using our Context example, we could use this as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;errors.NewMessage(Canceled, "context was canceled by user")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is a bit going on here. First we have &lt;code&gt;Message[T ~uint64]&lt;/code&gt;. This tells us that a &lt;code&gt;Message&lt;/code&gt; requires some type whose underlying value is &lt;code&gt;uint64&lt;/code&gt; (&lt;code&gt;~&lt;/code&gt; indicates underlying value). Since &lt;code&gt;Canceled&lt;/code&gt; is of &lt;code&gt;type ContextError uint64&lt;/code&gt;, that satisfies this type constraint. So what does that give us? Well now we know &lt;code&gt;Error&lt;/code&gt; is of type &lt;code&gt;T&lt;/code&gt; so when we &lt;code&gt;switch&lt;/code&gt; on &lt;code&gt;Message.Error&lt;/code&gt;, this functions exactly like our simpler enum example from above. But now that we have this new struct, we can also pull out &lt;code&gt;Message.Message&lt;/code&gt; and log it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Takeaway: Use generic &lt;code&gt;T ~uint64&lt;/code&gt; to type structs to errors&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If we want a "no error" case for &lt;code&gt;Message&lt;/code&gt; then we could make a helper function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func Ok[T ~uint64]() Message[T] {
    return Message[T]{}
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since the default value of &lt;code&gt;uint64&lt;/code&gt; is 0 and our convention is that 0 is equivalent to "no error" then golang solves this perfectly for us.&lt;/p&gt;

&lt;h2&gt;
  
  
  What about &lt;code&gt;error&lt;/code&gt; and the &lt;code&gt;errors&lt;/code&gt; package?
&lt;/h2&gt;

&lt;p&gt;We simply do not need them anymore. In fact, you could just shadow  &lt;code&gt;error&lt;/code&gt; in all of your packages: &lt;code&gt;type error uint64&lt;/code&gt;, but I would not actually recommend that. It is just more evidence that standard error handling in golang is more like a guideline than an actual rule.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Admittedly, this is not perfect. Returning "no error" is particularly funky. However, what this shows is that we do not need any extra packages to handle fancy stuff in order to get into better golang error handling. Golang already provides everything we need, we just have to define a new convention using those pieces and improve our code.&lt;/p&gt;

</description>
      <category>go</category>
      <category>design</category>
      <category>errors</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Left Handed in a Right Handed World</title>
      <dc:creator>Wesley Powell</dc:creator>
      <pubDate>Sat, 20 Aug 2022 18:09:48 +0000</pubDate>
      <link>https://dev.to/wspowell/left-handed-in-a-right-handed-world-3on3</link>
      <guid>https://dev.to/wspowell/left-handed-in-a-right-handed-world-3on3</guid>
      <description>&lt;p&gt;About 90% of the human population are right hand dominant &lt;sup&gt;&lt;a href="https://en.wikipedia.org/wiki/Handedness"&gt;[wikipedia]&lt;/a&gt;&lt;/sup&gt;. Being left handed in a right handed world has challenges and differences that are not obvious to someone who is right handed. Let me know in the comments about your left handed experiences.&lt;/p&gt;

&lt;h2&gt;
  
  
  Daily Life
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Scissors
&lt;/h3&gt;

&lt;p&gt;Very few people that I have interacted with realize that scissors are the worst thing in the world for left handed use. The reason for this is that right handed scissors are designed with the cutting blade on top and when you squeeze it naturally pushes the blades together. This provides for a sharp clean cut. When used in the left hand the cutting blade flips to the bottom and the squeezing action actually forces the blades apart. Naturally, if the blades are not flush, it will not cut. The solution for left handed use is to change hand posture and consciously torque the blades together as you cut. But obviously, this is incredibly uncomfortable and not very fun to use. If you know someone who is left handed, chances are they have a pair of left handed scissors.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dinner Table
&lt;/h3&gt;

&lt;p&gt;You sit down for dinner with family, friends, or date. You pick up a fork and start eating, but suddenly you are bumping elbows with the person next to you. This is not unfamiliar to lefties. Because the hand you use to eat with is likely different than those around you, your elbows move in the same space and eventually will collide. This has led lefties to heading this off and looking for the ends of tables where they will have no one to collide with.&lt;/p&gt;

&lt;p&gt;In some cultures, eating with your left hand is considered unsanitary and/or rude.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pens
&lt;/h3&gt;

&lt;p&gt;This is a weird one. Some pens have a twist in the middle to extend the ballpoint. I have never come across a left handed version of these. What happens is that the natural torque of your left hand as you write is opposite from your right hand and using it in your left will actually close the pen as you write.&lt;/p&gt;

&lt;h3&gt;
  
  
  Computers
&lt;/h3&gt;

&lt;p&gt;If you pick any public computer and sit down at it, chances are the mouse is on the right side. If you are left handed, this means you have to move the mouse to the other side, which could be problematic in small spaces like keyboard trays. It also means that you probably have to flip the primary buttons in the mouse settings. I say "probably" because I lived for a long time using right handed buttons in my left hand simply because it is annoying to change constantly.&lt;/p&gt;

&lt;p&gt;A slight advantage I have obtained is the ability to use a mouse in either hand. This has lead me to heading off RSI in my primary mouse hand. Whenever my hand starts to hurt, I just flip my mouse to the other side for a few weeks. I am not as precise in my right hand, but for most tasks it works out just fine.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cups/Mugs
&lt;/h3&gt;

&lt;p&gt;Depending on your personal preference, you may want to stare at a logo or slogan as you drink your preferred hot beverage. When you drink with your left hand, that flips and you may or may not have your preferred side facing you. This is a small thing, but may become a slight annoyance, or hidden benefit.&lt;/p&gt;

&lt;h2&gt;
  
  
  PC Gaming
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Hardware
&lt;/h3&gt;

&lt;p&gt;When playing PC games, one annoying aspect is that WASD is on the left side of a long keyboard. So when you want to game you have to slide the keyboard so far over to the right that you have to make room or it hangs off the edge of your desk. And if you have it in a keyboard tray then you just have to move it out of the tray. Additionally, if you are gaming on a laptop there is not much you can do.&lt;/p&gt;

&lt;p&gt;Another interesting thing is that WASD controls fits your hand differently so pressing certain buttons just doesn't feel right so sometimes you have to remap the buttons. Also, I have used my palm to jump (space bar) my entire life. However, I have never understood why right handed gamers decided to put crouch and sprint (CTRL, SHIFT) under your pinkie, which is one of the most frequent movements controlled by the weakest finger. I have always felt like I have had an advantage there since I can use my thumb and index finger for those controls. But most other actions have you reaching out away from your right hand (G, F, T, V, etc) for things like interact, grenades, and melee which is more natural. As left handed, I have to use my pinkie for those which is a struggle and I mess up quite a bit.&lt;/p&gt;

&lt;p&gt;Not to mention, all of the best hardware options are only right handed. In fact, I just ordered a left handed (ambidextrous actually) gaming mouse off of Amazon and the next day the order was canceled due to "lack of availability". Imagine not being able to use your favorite hardware simply because it was not available in your handedness. Imagine reading about a device and getting super excited only to find that you could not use it.&lt;/p&gt;

&lt;h3&gt;
  
  
  User Interface
&lt;/h3&gt;

&lt;p&gt;Mouse clicks in menus sometimes are hard coded to be right handed. Some of these games are high profile high revenue games like The Elder Scrolls and Rainbow Six: Siege. In games such as these, menus are hard code to right handed even if you change setting in the OS. Fixing this directly in the control mappings does not help since that only affects direct gameplay. Constantly swapping back and forth between button schemes is definitely draining and a frequent source of miss clicks.&lt;/p&gt;

&lt;p&gt;Has anyone ever noticed that essentially every game avatar is right handed? It sure would be nice to have an option to flip that and have it be left handed, especially for FPS games. Shout out to, Link, the best left handed avatar out there! &lt;em&gt;&lt;a href="https://www.cbr.com/zelda-botw-left-handed-link/"&gt;We do not talk about Breath of the Wild Link or the Wii&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Firearms
&lt;/h2&gt;

&lt;p&gt;If you have ever shot any side ejecting rifle, you may not realize that if you used it left handed you will get hot bullet casings and gun powder to your arm unless you hold it funky (and potentially unsafe). While not usually an issue you come across very often, I bet being left handed in the military can be rough. I would imagine that not being able to pick up any fellow soldiers firearm and use it without getting burns is an issue.&lt;/p&gt;

&lt;h2&gt;
  
  
  Left Footed
&lt;/h2&gt;

&lt;p&gt;I am not also left footed but I am aware that there might be extra challenges for those who are. I would be interested to hear about any left footed challenges in the comments! One in particular I have always wondered is if there are any issues with the gas/brake pedals in vehicles.&lt;/p&gt;

&lt;p&gt;* All credit and rights for the cover image belong to &lt;a href="https://www.huffpost.com/entry/12-little-known-facts-about-left-handers_n_55d39e97e4b0ab468d9ec794"&gt;HuffPost&lt;/a&gt;&lt;/p&gt;

</description>
      <category>a11y</category>
    </item>
    <item>
      <title>Better Golang Error Handling</title>
      <dc:creator>Wesley Powell</dc:creator>
      <pubDate>Mon, 15 Aug 2022 04:11:12 +0000</pubDate>
      <link>https://dev.to/wspowell/better-golang-error-handling-182m</link>
      <guid>https://dev.to/wspowell/better-golang-error-handling-182m</guid>
      <description>&lt;p&gt;&lt;em&gt;&lt;strong&gt;TL;DR Skip to the end to see the code&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Motivation
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://dev.to/wspowell/golang-error-everything-you-know-is-wrong-o7j"&gt;I recently reviewed&lt;/a&gt; various reasons why the built-in golang &lt;code&gt;error&lt;/code&gt; is not great. In fact, if you &lt;a href="https://www.google.com/search?q=golang+error+handling" rel="noopener noreferrer"&gt;Google "golang error handling"&lt;/a&gt; you will find many other blogs with various takes on how to navigate errors in golang. Even though the topic has seen lots of conversation, there really has not been much progress.&lt;/p&gt;

&lt;p&gt;So I will throw out yet another blog post on golang error handling.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start Fresh
&lt;/h2&gt;

&lt;p&gt;First thing I will propose, though controversial, is to throw out everything there is about golang errors. Do not use &lt;code&gt;error&lt;/code&gt;. Do not use the &lt;code&gt;"errors"&lt;/code&gt; package. Just throw it all away (it was probably just giving you anxiety anyway). &lt;code&gt;error&lt;/code&gt; was more like a guideline anyway.&lt;/p&gt;

&lt;p&gt;Now that we have no error handling we are open to a new world of possibilities. What does an error look like? What data should be contained in an error? Once created, how do we handle an error? Can we extend errors now? In this blog, I propose an error of the simplest possible terms so that it may be extended only as needed.&lt;/p&gt;

&lt;h2&gt;
  
  
  The &lt;code&gt;Error&lt;/code&gt; Type
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;type Error[T ~string] string&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Yep. Let us just start with a new type called &lt;code&gt;Error&lt;/code&gt;. Note that we could also just reuse &lt;code&gt;error&lt;/code&gt; since it is not a keyword, but that gets slightly messy. This new &lt;code&gt;Error&lt;/code&gt; is simply just a &lt;code&gt;string&lt;/code&gt;. &lt;code&gt;string&lt;/code&gt; is a great starting point because errors messages are usually strings that are human readable.&lt;/p&gt;

&lt;p&gt;Right away, we essentially have everything we need. An error could be &lt;code&gt;"whoops"&lt;/code&gt; and no error would be &lt;code&gt;""&lt;/code&gt; (empty string). To make the usage around this a bit nicer to read, we can attach &lt;code&gt;IsSome() bool&lt;/code&gt; and &lt;code&gt;IsNone() bool&lt;/code&gt;. These two helper functions would just check if the value is &lt;code&gt;""&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Create an error
err := errors.New[string]("whoops")

// Handle the error.
if err.IsSome() {
    // Do something useful with the error.
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While this sufficiently covers creating errors and error handling, there is more that we can do. In fact, while these helper functions may remain on a possible real implementation, I would propose never using them. The reason? There is actually an even better approach that utilizes that generic &lt;code&gt;T&lt;/code&gt; on the &lt;code&gt;Error&lt;/code&gt; type.&lt;/p&gt;

&lt;h2&gt;
  
  
  Error Enums
&lt;/h2&gt;

&lt;p&gt;One major issue with golang is the lack of enums. However, there are ways to make enums that linters will recognize. This usually follows in the form of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const EnumType &amp;lt;some type&amp;gt;

const (
    EnumTypeA = EnumType(&amp;lt;some value&amp;gt;)
    EnumTypeB = EnumType(&amp;lt;some value&amp;gt;)
    // ... and so on
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Taking some inspiration from rust, it would be amazing if we could have something similar to &lt;code&gt;match&lt;/code&gt; that would force us to cover all enum cases. Fortunately, the next best thing is the &lt;a href="https://golangci-lint.run/usage/linters/#exhaustive" rel="noopener noreferrer"&gt;exhaustive linter&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;In the current version of golang &lt;code&gt;error&lt;/code&gt;, the only way to create a sentinel error is to do &lt;code&gt;var ErrMyError = errors.New("whoops")&lt;/code&gt;. But there is a problem with this: it is a variable, not constant. So this is not a real fake enum that linters recognize. It also does not make sense for these to be mutable globals.&lt;/p&gt;

&lt;p&gt;The proposed new &lt;code&gt;Error&lt;/code&gt; type solves this issue by accepting a &lt;code&gt;T ~string&lt;/code&gt;. This means the type of the &lt;code&gt;Error&lt;/code&gt; itself is different depending on &lt;code&gt;T&lt;/code&gt;. &lt;code&gt;T&lt;/code&gt; is also constrained to &lt;code&gt;~string&lt;/code&gt; which means two things: &lt;code&gt;T&lt;/code&gt; can be cast to &lt;code&gt;string&lt;/code&gt;, &lt;code&gt;T&lt;/code&gt; can be const. Note that even though &lt;code&gt;T&lt;/code&gt; is not stored as a value in the &lt;code&gt;Error&lt;/code&gt; type, we can still reference it because it is part of the type definition. This allows us to keep &lt;code&gt;Error&lt;/code&gt; as a simple &lt;code&gt;string&lt;/code&gt; while being able to cast it into &lt;code&gt;T&lt;/code&gt;. Taking some more inspiration from rust, we can add a function to &lt;code&gt;Error&lt;/code&gt; that does this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func (self Error[T]) Into() T {
    return T(self)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While this all feel like over-complicated code since it is all just syntax sugar around &lt;code&gt;string&lt;/code&gt;, it enables us to now have error handling like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;switch err := StringError(0); err.Into() {
default:
    fmt.Println(err)
case errors.ErrNone:
    fmt.Println("no error")
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For a simple &lt;code&gt;Error[string]&lt;/code&gt;, &lt;code&gt;default&lt;/code&gt; catches an error if it exists and &lt;code&gt;case errors.ErrNone&lt;/code&gt; catches the "no error" case. However, if we have an error enum then that enum type is the &lt;code&gt;T&lt;/code&gt; and &lt;code&gt;Into() T&lt;/code&gt; returns the error of that type. This looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;_, err = EnumError(3)
switch err.Into() {
case ErrMyErrorOne:
    fmt.Println(err)
case ErrMyErrorTwo:
    fmt.Println(err)
case ErrMyErrorThree:
    fmt.Println(err)
case errors.ErrNone:
    fmt.Println("no error")
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice there is a case for each enum that was defined and there is no &lt;code&gt;default&lt;/code&gt;. Technically, to be thorough &lt;code&gt;default&lt;/code&gt; should be included but if you have to return an error of a certain type then that should not happen, but it could.&lt;/p&gt;

&lt;p&gt;What about missing cases? If there is a missing case, the exhaustive linter will point it out and let you know that you did not include everything.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzoaelbpc5pepq8qwvka1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzoaelbpc5pepq8qwvka1.png" alt="missing cases in switch of type SampleError: ErrMyErrorOne, ErrMyErrorThree, ErrMyErrorTwo (exhaustive)"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Extending &lt;code&gt;Error&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;The golang &lt;code&gt;error&lt;/code&gt; will let you extend it and do whatever you want and any viable replacement should allow the same functionality. It very well may be that a &lt;code&gt;string&lt;/code&gt; is not sufficient for some use cases. In that case, we still need a way of extending &lt;code&gt;Error&lt;/code&gt; without having to change the pattern.&lt;/p&gt;

&lt;p&gt;Let us assume that we desire a unique error code for tracking/debugging purposes that is assigned to each &lt;code&gt;Error&lt;/code&gt;. We can extend &lt;code&gt;Error&lt;/code&gt; by creating our new &lt;code&gt;type MyError[T ~string] struct&lt;/code&gt; and embedding &lt;code&gt;Error&lt;/code&gt; in it. &lt;code&gt;MyError&lt;/code&gt; now has access to the same functionality that &lt;code&gt;Error&lt;/code&gt; does while also having the benefit of storing an extra value for an error ID.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type MyError[T ~string] struct {
    errors.Error[T]

    // Other data defined here.
    errId int
}

func New[T ~string](err T, errId int) MyError[T] {
    return MyError[T]{
        Error: errors.New(err),
        errId: errId,
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The usage is exactly the same except &lt;code&gt;MyError[T]&lt;/code&gt; is returned from a function instead of &lt;code&gt;Error[T]&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Advantages/Benefits
&lt;/h2&gt;

&lt;p&gt;So why go through all this effort? Maybe you are satisfied with golang &lt;code&gt;error&lt;/code&gt; and need more convincing? Aside from what has already been stated in the sections above, there are more benefits gained from this proposed approach.&lt;/p&gt;

&lt;h3&gt;
  
  
  Performance
&lt;/h3&gt;

&lt;p&gt;The proposed &lt;code&gt;Error&lt;/code&gt; is actually more performant than &lt;code&gt;error&lt;/code&gt;. This is because &lt;code&gt;error&lt;/code&gt; is an interface which means that literally every error ever created requires a memory allocation. In straight up benchmark comparisons, this is not all that much, but all of those allocations add up.&lt;/p&gt;

&lt;p&gt;Here is my non-official benchmark comparison between creating a new golang &lt;code&gt;error&lt;/code&gt; and an &lt;code&gt;Error&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;error
24.96 ns/op       16 B/op          1 allocs/op
Error
5.557 ns/op        0 B/op          0 allocs/op
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A ~4.5x improvement is not too shabby even though we are talking about nanoseconds here.&lt;/p&gt;

&lt;h3&gt;
  
  
  Self Documenting Code
&lt;/h3&gt;

&lt;p&gt;Documentation is always a struggle. The moment code changes, the documentation must be updated. However, using enums as types in &lt;code&gt;Error&lt;/code&gt; allows us to clearly see what errors a function returns. I have used some comments like this before but it just does not feel great:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Foo does stuff
//
// Errors:
//   * ErrFooFailure
func Foo() error { ... }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead, we can now have something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type SampleError string

const (
    ErrMyErrorOne   = SampleError("error one")
    ErrMyErrorTwo   = SampleError("error two")
    ErrMyErrorThree = SampleError("error three")
)

func EnumError(which int) (int, errors.Error[SampleError]) {
    switch which {
    case 1:
        return 1, errors.New(ErrMyErrorOne)
    case 2:
        return 2, errors.New(ErrMyErrorTwo)
    case 3:
        return 3, errors.New(ErrMyErrorThree)
    default:
        return 0, errors.None[SampleError]()
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is clear, ties in with the compiler, and is easy to understand. The code simply documents itself.&lt;/p&gt;

&lt;h3&gt;
  
  
  "Accept interfaces, return structs"
&lt;/h3&gt;

&lt;p&gt;This is a general rule in golang code, but &lt;code&gt;error&lt;/code&gt; completely breaks this since it is an interface. Once returned, there is no way to operate on the error except through helper functions like &lt;code&gt;errors.As()&lt;/code&gt;. Being required to call &lt;code&gt;Unwrap()&lt;/code&gt;, &lt;code&gt;errors.As()&lt;/code&gt;, etc means there is uncertainty, which usually leads to bugs. The uncertainty I am referring to is all of the issues mentioned in my previous post, such as error formatting. Since &lt;code&gt;Error&lt;/code&gt; is not an interface, we can operate on it with certainty.&lt;/p&gt;

&lt;h3&gt;
  
  
  No Wrapping
&lt;/h3&gt;

&lt;p&gt;This touches on another small performance benefit. When &lt;code&gt;"errors"&lt;/code&gt; was abandoned for this proposal, we also dumped all of that error wrapping insanity. &lt;code&gt;error&lt;/code&gt; is used as a linked list. Since &lt;code&gt;Error&lt;/code&gt; is intended to be immutable and "one shot", there is no chain of errors that must be traversed to check if we got some type of &lt;code&gt;error&lt;/code&gt;. And with the recent release of &lt;code&gt;go1.19&lt;/code&gt;, if you happened to have a large set of errors then the proposed &lt;code&gt;switch&lt;/code&gt; error handling pattern would benefit from a &lt;a href="https://tip.golang.org/doc/go1.19#compiler" rel="noopener noreferrer"&gt;switch jump table&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next Steps
&lt;/h2&gt;

&lt;p&gt;This is proposal is something I am still flushing out, but I feel like it shows real promise. In fact, in just writing this I changed a few things, but the core concept remains. I will keep iterating and experimenting my personal projects, though it may take some some convincing to use an iteration of this in actual projects.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR Just Show Me The Code!
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;error.go&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package errors

import (
    "fmt"
)

const ErrNone = ""

func None[T ~string]() Error[T] {
    return Error[T]("")
}

func New[T ~string](format T, values ...any) Error[T] {
    return newError(format, values...)
}

type Error[T ~string] string

func newError[T ~string](format T, values ...any) Error[T] {
    var err string
    if len(values) != 0 {
        // Do not call fmt.Sprintf() if not necessary.
        // Major performance improvement.
        // Only necessary if there are any values.
        err = fmt.Sprintf(string(format), values...)
    } else {
        err = string(format)
    }

    return Error[T](err)
}

func (self Error[T]) IsNone() bool {
    return self == ""
}

func (self Error[T]) IsSome() bool {
    return !self.IsNone()
}

func (self Error[T]) Into() T {
    return T(self)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;error_example_test.go&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package errors_test

import (
    "fmt"

    "experimentation/errors"
)

func StringError(which int) errors.Error[string] {
    switch which {
    case 1:
        return errors.New("error: %s", "whoops")
    default:
        return errors.None[string]()
    }
}

func ExampleStringError() {
    switch err := StringError(0); err.Into() {
    default:
        fmt.Println(err)
    case errors.ErrNone:
        fmt.Println("no error")
    }

    switch err := StringError(1); err.Into() {
    default:
        fmt.Println(err)
    case errors.ErrNone:
        fmt.Println("no error")
    }

    // Output:
    // no error
    // error: whoops
}

type SampleError string

const (
    ErrMyErrorOne   = SampleError("error one")
    ErrMyErrorTwo   = SampleError("error two")
    ErrMyErrorThree = SampleError("error three")
)

func EnumError(which int) (int, errors.Error[SampleError]) {
    switch which {
    case 1:
        return 1, errors.New(ErrMyErrorOne)
    case 2:
        return 2, errors.New(ErrMyErrorTwo)
    case 3:
        return 3, errors.New(ErrMyErrorThree)
    default:
        return 0, errors.None[SampleError]()
    }
}

func ExampleEnumError() {
    _, err := EnumError(0)
    switch err.Into() {
    default:
        fmt.Println(err)
    case errors.ErrNone:
        fmt.Println("no error")
    }

    _, err = EnumError(3)
    switch err.Into() {
    case ErrMyErrorOne:
        fmt.Println(err)
    case ErrMyErrorTwo:
        fmt.Println(err)
    case ErrMyErrorThree:
        fmt.Println(err)
    case errors.ErrNone:
        fmt.Println("no error")
    }

    // Output:
    // no error
    // error three
}

type MyError[T ~string] struct {
    errors.Error[T]

    // Other data defined here.
    errId int
}

func New[T ~string](err T, errId int) MyError[T] {
    return MyError[T]{
        Error: errors.New(err),
        errId: errId,
    }
}

func (self MyError[T]) String() string {
    return fmt.Sprintf("error: %s, id: %d", self.Error, self.errId)
}

func MyErrorFn() MyError[string] {
    return New("whoops", 123)
}

func ExampleMyError() {
    switch err := MyErrorFn(); err.Into() {
    default:
        fmt.Println(err)
    case errors.ErrNone:
        fmt.Println("no error")
    }

    // Output:
    // error: whoops, id: 123
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>go</category>
      <category>programming</category>
      <category>design</category>
      <category>errors</category>
    </item>
    <item>
      <title>Golang 'error': Everything you know is wrong</title>
      <dc:creator>Wesley Powell</dc:creator>
      <pubDate>Thu, 04 Aug 2022 04:45:38 +0000</pubDate>
      <link>https://dev.to/wspowell/golang-error-everything-you-know-is-wrong-o7j</link>
      <guid>https://dev.to/wspowell/golang-error-everything-you-know-is-wrong-o7j</guid>
      <description>&lt;h2&gt;
  
  
  "errors as linked lists"
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The Attempted Concept
&lt;/h3&gt;

&lt;p&gt;The concept of errors as linked lists seems neat at first. You can define your own &lt;code&gt;error&lt;/code&gt; type, customize how it prints, and add extra information to it. Once instantiated, you can simply pass it up to the caller as a normal old &lt;code&gt;error&lt;/code&gt;. Callers of your function can then check to see if your &lt;code&gt;error&lt;/code&gt; &lt;code&gt;Is()&lt;/code&gt; another. Cool! Further even, you can add extra info to an &lt;code&gt;error&lt;/code&gt; that you wrap and bubble up. Awesome! &lt;code&gt;error&lt;/code&gt; is so flexible and powerful!&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;error&lt;/code&gt; Chain Of Pain
&lt;/h3&gt;

&lt;p&gt;You start setting up error handling in your first golang application and you find that you start running into problems. You find that you cannot both return an &lt;code&gt;error&lt;/code&gt; that &lt;code&gt;Is()&lt;/code&gt; both your custom error and the &lt;code&gt;error&lt;/code&gt; you just received. "That's fine", you think to yourself, "I should not have the caller rely on my implementation details anyway". So you return your API's own &lt;code&gt;error&lt;/code&gt; and move on.&lt;/p&gt;

&lt;p&gt;You then start working with some HTTP helper library that returns an &lt;code&gt;error&lt;/code&gt; if a request fails. Suddenly, you realize that you also need to know if that &lt;code&gt;error&lt;/code&gt; &lt;code&gt;Is()&lt;/code&gt; a &lt;code&gt;context.DeadlineExceeded&lt;/code&gt; from the request timing out. "That's fine", you think again, "I know how to handle that!". That is when you realize that the &lt;code&gt;DeadlineExceeded&lt;/code&gt; error most likely originates from deep within that call stack and you would be relying on &lt;em&gt;their&lt;/em&gt; implementation details. Even worse, you realize, "What if the library I am using does not bubble up that &lt;code&gt;error&lt;/code&gt;, just as I did earlier? After all, that library could be catching it and returning their own errors too, or worse, that library calls yet another one that does". Suddenly, you realize that everything you knew and trusted about golang errors is wrong. You can no longer trust the &lt;code&gt;error&lt;/code&gt; chain to provide reliable consistent results from &lt;code&gt;Is()&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;error&lt;/code&gt; Format Catastrophe
&lt;/h3&gt;

&lt;p&gt;I would suggest reading this blog about &lt;a href="https://dr-knz.net/go-error-printing-catastrophe.html"&gt;the catastrophe of golang error printing&lt;/a&gt;. This blog discusses yet another failure of the golang &lt;code&gt;error&lt;/code&gt; pattern, that if you have a chain of errors and if &lt;em&gt;any&lt;/em&gt; of them do not implement &lt;code&gt;Unwrap() error&lt;/code&gt; (an optional interface implementation for &lt;code&gt;error&lt;/code&gt;s), then your whole chain breaks down. It also goes into detail about the issue of calling &lt;code&gt;Format()&lt;/code&gt; on the &lt;code&gt;error&lt;/code&gt; chain.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;error&lt;/code&gt; Handling Problems
&lt;/h3&gt;

&lt;p&gt;One issue that many golang devs might not realize is that errors are constantly being shadowed. This is not usually a problem because once an &lt;code&gt;error&lt;/code&gt; is encountered, generally, the function returns. Consider the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if fooResult, err := foo(); err != nil {
    if barResult, err := bar(); err != nil { // err shadows previous err
        ...
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;err&lt;/code&gt; returned by &lt;code&gt;bar()&lt;/code&gt; shadows the &lt;code&gt;err&lt;/code&gt; returned by &lt;code&gt;foo()&lt;/code&gt;. This is probably not going to cause any problems but you do end up with two instances of &lt;code&gt;err&lt;/code&gt; in the same function. Anytime you have shadowed variables it is a code smell. Unfortunately, that means all of golang error handling smells. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://go.dev/play/p/wwGjCj9rNu4"&gt;Side note&lt;/a&gt;: golang gets away with this because it makes an exception on the &lt;code&gt;:=&lt;/code&gt; operator that if at least one variable is newly declared, then it is fine. That is why you can redeclare &lt;code&gt;err&lt;/code&gt; constantly. It just bends the rules a bit to fit the pattern, but causes variable shadowing in the process.&lt;/p&gt;

&lt;p&gt;The only way to solve this is by not shadowing those variables, but the solution is not pretty to read:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var fooResult struct{}
var err error
if fooResult, err = foo(); err != nil {
    var barResult struct{}
    if barResult, err = bar(); err != nil {
        ...
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So the solution is to declare your variables before assignment. Following that train of thought, if you think this issue is solved with named returns, think again. Let's take &lt;a href="https://go.dev/play/p/8vjo3ZDcnlu"&gt;this example&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func task() (err error) {
    if err = foo(); err != nil {
        if err := bar(); err != nil {
            ...
        }
    }
    return
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Whoops! You just typo-ed that &lt;code&gt;:=&lt;/code&gt; on &lt;code&gt;bar()&lt;/code&gt;. The compiler says,👍. The function works. But only &lt;code&gt;foo()&lt;/code&gt; errors will ever be returned. This is a logic bug, plain and simple. It is easy to fix, but could be difficult to find.&lt;/p&gt;

&lt;h3&gt;
  
  
  The "Solution"
&lt;/h3&gt;

&lt;p&gt;How do you solve these problems? Short answer: you don't. At least, not without changing the core golang pattern and probably having a few debates with your coworkers about best practices. This is a problem the language itself must address.&lt;/p&gt;

&lt;h2&gt;
  
  
  Experimental Alternative
&lt;/h2&gt;

&lt;p&gt;Frustrations with &lt;code&gt;error&lt;/code&gt; has led me to the propose following changes (that you can try right now!):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Abandon &lt;code&gt;error&lt;/code&gt; and never look back

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;errors&lt;/code&gt; package becomes dead code as a result&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;fmt&lt;/code&gt; directive &lt;code&gt;"%w"&lt;/code&gt; can go away too&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Make a &lt;code&gt;type Error struct {}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Make errors values, not references&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;type error Error&lt;/code&gt;, for good measure

&lt;ul&gt;
&lt;li&gt;Yes, you can do that. Get that thing outta here!&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Make a &lt;code&gt;type Result[T any] struct {}&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now you can live in golang free of the burdens of the built in &lt;code&gt;error&lt;/code&gt; interface. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func task() Result[int] {
    fooResult := foo()
    if !fooResult.IsOk() {
        return fooResult
    }

    barResult := bar()
    if !barResult.IsOk() {
        return Err[int](barResult.Error())
    }

    return Ok(1)
}

func foo() Result[int] {
    return Ok(2)
}

func bar() Result[float32] {
    return Err[float32]("whoops")
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://go.dev/play/p/GDtuf6qJEhq"&gt;Goplay&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is a horrible example, but it demonstrates that you can easily change error handling for the better. Technically, this will impact consumers of this package who use golang &lt;code&gt;error&lt;/code&gt;, but the issues this will cause are same that exist already. Broken &lt;code&gt;Unwrap() error&lt;/code&gt; chains. Poor formatting standards. Leaking implementation details. You get the idea.&lt;/p&gt;

&lt;p&gt;If you noticed, this proposed pattern solves the issues noted in the above section. Errors are values (no wrapping involved), so no more weird chaining issues. Error printing is reliable since there is a defined error struct. Each function or package can define explicit Errors as part of its API that can be checked for by equivalence, not by &lt;code&gt;Is()&lt;/code&gt; chain detection. Result is a single value, so no more shadowed variables. If you want to add more info to your errors, you could embed &lt;code&gt;Error&lt;/code&gt; in your own &lt;code&gt;type ApiError struct {}&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A surprise benefit of this new pattern is that your errors no longer &lt;em&gt;automatically escape to the heap&lt;/em&gt; (hint: &lt;code&gt;error&lt;/code&gt; is an interface). That's right. Not only is this pattern easier to use and solves the issues of standard golang &lt;code&gt;error&lt;/code&gt;s, but it is more performant.&lt;/p&gt;

&lt;p&gt;More work obviously needs to be put into this before it can be useful in an actual project, but this is definitely a great start.&lt;/p&gt;

</description>
      <category>go</category>
      <category>programming</category>
      <category>design</category>
      <category>errors</category>
    </item>
    <item>
      <title>Golang Concurrency Jump Start</title>
      <dc:creator>Wesley Powell</dc:creator>
      <pubDate>Wed, 20 Jul 2022 03:55:14 +0000</pubDate>
      <link>https://dev.to/wspowell/golang-concurrency-jump-start-4d42</link>
      <guid>https://dev.to/wspowell/golang-concurrency-jump-start-4d42</guid>
      <description>&lt;h2&gt;
  
  
  Takeaways In This Post
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Only store primitives and immutable or read only values in Contexts&lt;/li&gt;
&lt;li&gt;Do not use Context to store application logic values&lt;/li&gt;
&lt;li&gt;Always create a main cancellable Context to allow goroutines to gracefully stop&lt;/li&gt;
&lt;li&gt;Check Context cancellation before and during long running tasks&lt;/li&gt;
&lt;li&gt;Use channels to logically partition concurrent work&lt;/li&gt;
&lt;li&gt;&lt;a href="https://go.dev/blog/codelab-share"&gt;Do not communicate by sharing memory; instead, share memory by communicating&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Context
&lt;/h2&gt;

&lt;p&gt;A &lt;a href="https://pkg.go.dev/context#Context"&gt;context.Context&lt;/a&gt; is a reference (because it is an interface) to an immutable key/value pair that is one node in a tree of Contexts. Each Context can lookup values using the recursive function &lt;code&gt;Value(key) any&lt;/code&gt; and check cancellation of the chain with &lt;code&gt;Done() &amp;lt;-chan struct{}&lt;/code&gt;. This structure allows values and cancel signals to be shared amongst numerous goroutines. This allows data to be shared safely. One major use case is profiling.&lt;/p&gt;

&lt;h3&gt;
  
  
  Common Context Pitfalls
&lt;/h3&gt;

&lt;p&gt;Context is commonly abused and misused by allowing values stored in the Context to be mutable and also by storing Contexts inside structs. Both of these mistakes lead to potential race conditions and other issues. Avoid storing maps, slices, references, and channels as Context values. Stick to primitives and struct values. Beware of references stored in struct values as those may also present race condition issues.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Takeaway: Only store primitives and immutable or read only values in Contexts&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Another issue is the tendency to use Context as a grab bag of application values. Keep in mind that the more values stored in the Context the longer look ups become, &lt;code&gt;O(n)&lt;/code&gt;. This pattern also makes debugging difficult since all of the values are "hidden". Pass the values you require as arguments.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Takeaway: Do not use Context to store application logic values&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A good practice to follow is always create an application Context before anything else. This allows the main to gracefully shutdown any running goroutines before exiting. Otherwise, goroutines will be halted mid-execution without any opportunity to stop.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hello, Concurrency!
&lt;/h2&gt;

&lt;p&gt;Basic "Hello, World!" main for concurrency.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cancel&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithCancel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Background&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

    &lt;span class="c"&gt;// Do parallel work...&lt;/span&gt;
    &lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;cancel&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Second&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://goplay.tools/snippet/IW85rmJcLuQ"&gt;goplay&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are improvements that should be done, but this will allow you to spawn any number of goroutines and allow five seconds for those to stop.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Takeaway: Always create a main cancellable Context to allow goroutines to gracefully stop&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Of course, goroutines do not simply stop by themselves. They have to monitor their Context for cancellations. A good way to do this is using &lt;code&gt;select&lt;/code&gt;. This will block until one of the &lt;code&gt;case&lt;/code&gt; branches becomes available.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Done&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
            &lt;span class="c"&gt;// Context cancelled. Should now stop processing work.&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;
        &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
            &lt;span class="c"&gt;// Process work&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://goplay.tools/snippet/8wUNUCyIyCi"&gt;goplay&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This function will run until its Context is cancelled. Because &lt;code&gt;default&lt;/code&gt; is always available, this will check the Done() channel for a value first and if nothing is ready then it will execute the &lt;code&gt;default&lt;/code&gt; branch. Even if a task is not continuously running, it is always a good idea to check the Context before performing an expensive operation, such as a &lt;a href="https://github.com/go-redis/redis/blob/e061db8c13fd6b5e007d73370873026e360719de/redis.go#L293"&gt;database query&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Takeaway: Check Context cancellation before and during long running tasks&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Data Concurrency
&lt;/h2&gt;

&lt;p&gt;When data needs to be accessed by the same goroutine, it is very easy to wrap that data in a &lt;code&gt;sync.Mutex&lt;/code&gt; and call it a day. This can lead to complex code and deadlocks. Golang provides a better way of communicating data between goroutines in the form of channels. You can think of channels like a hand off of data from one goroutine to another. That hand off blocks on both ends until both sides are ready. &lt;/p&gt;

&lt;p&gt;This pattern does a few things for you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Guarantees only one process is modifying data at a time&lt;/li&gt;
&lt;li&gt;Provides logical partitions of work that are easy to understand&lt;/li&gt;
&lt;li&gt;Decouples code that would otherwise rely on specific mutexes
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;readPacket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;packetChannel&lt;/span&gt; &lt;span class="k"&gt;chan&lt;/span&gt; &lt;span class="n"&gt;Packet&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Done&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
            &lt;span class="c"&gt;// Context cancelled. Should now stop processing work.&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;packet&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;packetChannel&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;

            &lt;span class="n"&gt;packet&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReadCount&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;
            &lt;span class="n"&gt;packetChannel&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;packet&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Millisecond&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://go.dev/play/p/aNUnIjIPuNz"&gt;goplay&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;readPacket()&lt;/code&gt; continuously checks the channel for new Packets, reads it, and then dumps it back onto the channel for another goroutine to process. If the channel is ever closed then we should stop. &lt;code&gt;ok&lt;/code&gt; becomes false once this happens. The small sleep in such a fast looping goroutine like this one allows time for other goroutines to process and prevents the CPU from maxing. &lt;/p&gt;

&lt;p&gt;Instead of taking a Packet blocking on mutex associated with it, we can freely pass the Packet between goroutines. The goroutine is an isolated slice of work to be done on the Packet. There may be other operations performing work on it in other goroutines, but those would never impact the thread safety of this goroutine task.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Takeaway: Use channels to logically partition concurrent work&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Takeaway: Do not communicate by sharing memory; instead, share memory by communicating&lt;/em&gt;&lt;/p&gt;

</description>
      <category>go</category>
      <category>tutorial</category>
      <category>programming</category>
      <category>concurrency</category>
    </item>
  </channel>
</rss>
