惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

The GitHub Blog
The GitHub Blog
Martin Fowler
Martin Fowler
Vercel News
Vercel News
U
Unit 42
Engineering at Meta
Engineering at Meta
aimingoo的专栏
aimingoo的专栏
MyScale Blog
MyScale Blog
Y
Y Combinator Blog
阮一峰的网络日志
阮一峰的网络日志
爱范儿
爱范儿
Apple Machine Learning Research
Apple Machine Learning Research
博客园_首页
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
B
Blog RSS Feed
N
Netflix TechBlog - Medium
GbyAI
GbyAI
F
Fortinet All Blogs
MongoDB | Blog
MongoDB | Blog
大猫的无限游戏
大猫的无限游戏
C
Check Point Blog
M
MIT News - Artificial intelligence
D
Docker
IT之家
IT之家
Stack Overflow Blog
Stack Overflow Blog

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
Go Error Handling: Annoying or Awesome?
Ryan Kikayi · 2026-05-25 · via DEV Community

For weeks when I was completely new to coding,I would always keep wondering; "What did I get myself into?", barely understanding what I'm looking at whenever I come across code that looked like this:

file, err := os.Open("data.txt")
if err != nil {
    log.Fatal(err)
}

data, err := io.ReadAll(file)
if err != nil {
    log.Fatal(err)
}

var result MyStruct
err = json.Unmarshal(data, &result)
if err != nil {
    log.Fatal(err)
}

Enter fullscreen mode Exit fullscreen mode

And for some reason it just did not make any sense to me at first; what do you mean we're using 9 lines of code just for error checking - has to be a joke?!
Over at YouTube, no tutorial was relatable. I mean there were tutorials on error checking for python, and javascript, but the concept wasn't just sticking.
Eventually, I ended up just copying chunks of code that I barely understood and pasted them into mine. Function returns two things, assign them to a variable and err. Basically pasting the if err != nil block was what I knew I was doing, the reason why? Not so much.
I wasn't reading the error half of the time, I was just calling log.Fatal(err) hoping it would never have to run.

Later on after getting comfortable with the language, I decided to work on a personal project - a CLI tool that reads config files, makes API calls, and writes its output to disk. Unfortunately, it broke in production, the problem;

data, _ := json.Marshal(payload)

Enter fullscreen mode Exit fullscreen mode

I had used a blank identifier _ to ignore the error completely - a habit I discovered to avoid having to write the check. This caused an API call to fail silently because the marshal was sending an empty body, and the API was rejecting it. And there I was, trying to debug something a single error message would have told me immediately.
I realized, in Go errors are not exceptions, they're values - like regular data, a functions gives back to you. When you call a function that can fail, it returns two things; the result, and an error. Go hands you the error and trusts you to deal with it. So basically, writing if err != nil is like saying "Something could go wrong here. What do you want to do about it?" in Go. Once I finally understood that I started seeing them as decision points.

So how do you actually make peace with it?

Early on, I used to write my errors the same: log.Fatal(err). When something broke, I'd get a vague message like unexpected end of JSON input with zero context about where in my program it came from.
The fix was wrapping errors with context using fmt.Errorf :

data, err := io.ReadAll(file)
if err != nil {
    return fmt.Errorf("failed to read config file: %w", err)
}

Enter fullscreen mode Exit fullscreen mode

The %w keeps the original error intact so you can still inspect it, but now every error message tells you what your program was trying to do when it failed. That one change made debugging significantly less painful.
The second thing that helped was setting up a snippet in my editor. In VS Code, typing ife and hitting Tab expands to:

if err != nil {
    return err
}

Enter fullscreen mode Exit fullscreen mode

The official Go extension already includes this — check your snippet settings if you haven't already. It sounds like a small thing, but when you're writing the pattern twenty times a day, not having to type it from scratch every time genuinely reduces the friction.

So — annoying or awesome?

Honestly? Both. Annoying at first, awesome once you understand why it exists.
Go made a deliberate choice to make error handling visible and local, rather than something that silently bubbles up through your stack and crashes things in ways you didn't expect. Every if err != nil is a decision point baked directly into your code. You always know where an error came from. You always have to decide what to do with it.
For a first language, that turned out to be a surprisingly good environment to learn in. I couldn't ignore problems — Go wouldn't let me. And when things went wrong, the error was almost always exactly where Go said it was.
Would I have picked a different first language if someone had warned me about this pattern? Maybe. Am I glad I stuck with Go? Absolutely.

If you're learning Go right now, I'm curious — what part of the language caught you off guard the most? Drop it in the comments.