Hacker News new | ask | show | jobs
by yawboakye 2762 days ago
Go optimizes for fast compilation, as such the language has fewer internal checks for only the absolutely necessary. In my opinion, to be able to continue execution when an error happened earlier could be a blessing or a curse, and it depends on the programmer. I've been writing Go for 2 years now and I don't have a single case where I accidentally ignored an error. I have ignored errors, but usually for operations whose end result I don't care about or doesn't affect what happens next in the program.

There's also a recommended way of dealing with errors. I may not state it correctly but basically you build a pipeline of operations for a data type that represents the arguments (or data) of the operations. For example, to compress an image given a URL:

  type Image struct {
    src string
    bytes []byte
    width uint
    height uint
    err error
  }
  
  func NewImage(src string) Image {
    return Image{src: src}
  }

  func (img Image) Get() {
    if err != nil {
      return
    }
    ...
    // Set error value if this operation fails
  }
  
  func (img Image) Compress {
    if err != nil {
      return
    }
    ...
    // Set error value if this operation fails
  }
  
  func (img Image) Err() error { return img.err }
  
  img := NewImage("https://image.src/random-image.png")
  img.Get()
  img.Compress()
  if img.Err() != nil {
    // handle error just once
  }
1 comments

this does work... but it also requires two very significant points.

1: you must do this wrapping yourself, for everything you wish to simplify, as few libs do it.

2: you now have non-standard error handling and your tools will not warn you if you handle it wrong.

the second one, to me, is borderline fatal for this pattern. You can't look at this code and realize it's missing error handling (or doing it incorrectly), and you can't run `errcheck` to tell you that e.g. you're missing `err := img.Get()`.