error handling as a first-class concern
Imagine cooking a meal where you only plan for everything going right - the oven works, no pan boils over, no guest is allergic. The first time anything goes wrong, dinner is ruined and you have no plan. Most of the hard part of real cooking, and of real programs, is what you do when something fails. Treating error handling as a first-class concern means you design for failure from the start, not as an afterthought bolted on once the 'happy path' already works.
Concretely, almost everything a systems program does can fail: opening a file can fail (the file is missing), allocating memory with malloc() can fail (it returns a null pointer), reading from a socket can fail (the connection dropped), writing to disk can fail (the disk is full). A program that takes errors seriously asks, for every one of these operations, 'what do I do if this fails right here?' before it asks 'what do I do when it works?'. The error path - the code that runs on failure - is real code that must be written, read, and tested with the same care as the success path, not a vague 'this should never happen' comment.
Why it matters: in systems programming the cost of a sloppy error path is unusually high. A web page that mishandles an error shows a broken layout; a database or kernel that mishandles an error can corrupt data, leak resources until the machine grinds to a halt, or crash every program that depended on it. The honest truth is that error handling is often more than half the code in a robust systems program, and the difference between code that 'works on my machine' and code that survives the real world is almost entirely in how it behaves when things go wrong.
Compare two ways of writing the same line. Careless: char *buf = malloc(n); buf[0] = 'A'; - if malloc() returned NULL because memory ran out, that write crashes (or worse, corrupts memory). Careful: char *buf = malloc(n); if (buf == NULL) { /* report and bail out cleanly */ return -1; } buf[0] = 'A'; - the failure of malloc() is a planned-for case, not a surprise.
The same operation; the careful version treats failure as a normal, expected case.
First-class does not mean handling every error in every function - it means consciously deciding for each failure whether to handle it, pass it up, or abort. The mistake is not deciding at all and silently ignoring the failure.