This post is written as a follow-up on Go’s Error Handling Sucks – A quantitative analysis upon the request of Herb Sutter who asked for a rough percentage of function calls that return error information to all function calls.

For this purpose, I have used the following regex for capturing function calls that return an error:

[a-zA-Z0-9_]*[eE]rr(or)? *:?= *([a-zA-Z0-9_]*\.)*[a-z-A-Z0-9_]+\(

and the following regex for capturing any function call:

([a-zA-Z0-9_]*\.)*[a-z-A-Z0-9_]+\(

The first regex relies on the convention that error is the last (or the only) value of any function that returns error information.

The second regex has the following shortcomings which should be understood:

  • Casts are mistaken as function calls. E.g. ENFILE = syscall.Errno(0x17)
  • Counting built-in “functions” such as len, append etc might be undesirable.
  • Function definitions, imports, and consts are confused as function calls, but I filtered them in my calculations.

Lastly, I have used the following commands to count:

ag --go --stats-only "[a-zA-Z0-9_]*[eE]rr(or)? *:?= *([a-zA-Z0-9_]*\\.)*[a-z-A-Z0-9_]+\\("

ag --go -v "func|const \\(|import \\(" | ag --stats-only "([a-zA-Z0-9_]*\\.)*[a-z-A-Z0-9_]+\\("

Here are the results:

  # of Calls Returning error # of Function Calls Ratio
Kubernetes 83,442 740,385 0.1127
Go 27,741 482,546 0.0575
Moby (Docker) 37,044 310,736 0.1192
Cockroach DB 24,498 254,926 0.0961
Mattermost (server) 22,737 214,756 0.1059
etcd 13,761 135,957 0.1012
Syncthing 2,436 25,472 0.0956
Hugo 1,876 23,983 0.0782
Helm 1,927 11,443 0.1684
Gin 242 5,307 0.0456
TOTAL 215,704 2,205,511 0.0978

For the record, here are the repositories used and their respective commits: