The web today is full of silent failures. I've noticed this all the time at work and in my personal business. If loading some resource runs into trouble, it's simply not feasible for the Node.js or React or PHP to surface an error to the user.
Chris says that the loading of sub-resources is a different matter. Well, the most common silent failure I have is not due to status codes per se, but because of my DNS-based adblocker, many sub-resources fail to load (GET or POST) with a network error (TCP RST). Unless a blocked domain corresponds to the front page I visit in a URL, the unavailable resource represents a silent failure, and I have foolishly contacted Support desks multiple times because my own use of the adblocker caused a silent failure that was difficult to diagnose.
In fact, I now have no way of knowing what web apps are like without an adblocker. Because all my devices use the same configuration, and it's non-trivial to disable it, I simply don't know what I am missing. Indeed, in the case of one web app which I've used as a PWA, it was simply missing features that I knew should have been there, and whitelisting enough domain names caused those features to re-appear.
You'd like to think that the owners of those sites would fix them. A site shouldn't just not work if it can't access a certain JavaScript file - it should at least warn you of the problem.
What's the point of the PiHole in that setup? If the router doesn't have the storage for as large a cache you're still only using the dnsmasq part of PiHole by the sounds of it? (Not to mention most consumer routers support USB mass storage?)
They have a feature where if you're a free user, and you exceed your query quota for the month, they turn off all features and it acts like a normal resolver.
For some reason, there is no access to such a setting to do it manually, and I am a subscriber now, too.
There are profiles that can be configured separately, but even just to activate an alternate profile, one must reconfigure the DNS settings on the devices.
From the user's point of view, yes, that is intended behavior. But the browser can't know that, all it sees is a dropped connection. For all it knows, there could be an actual issue with the network.
But unless you open the dev tools' network tab, you don't know about that request failing.
TCP RST is indeed considered a transient failure, and the RFCs specify that it should be retried several times before giving up.
My ad blocker returns "0.0.0.0" for A records, which in practice means attempts to connect to 127.0.0.1, which isn't running a server of any kind on port 443/tcp or 80/tcp. So a standards-compliant client would really hang awhile, or hold rendering, until several connects have been attempted and they all failed.
In the context of your comment, I was amused by how my own ad-blocker failed to properly show the (image on the) 404 page, since it is loaded from a different domain :D
This is why I run my DNS-based ad blocking solution through a VPS. It's trivial to toggle the VPN on/off on desktop or mobile. On desktop I have a single key to swap my network. On mobile, a gesture followed by two taps does the same.
I’m not sure if we are talking about PiHole here, but I just log into the web interface and whitelist or temporarily disable blocking. Not as trivial as a browser extension, but still quite easy and fast.
Also was confused by this sentence. I have worked on several Node, React, and even PHP (albeit a long time ago!) applications, and every single one of them caught and surfaced internal server errors. Never was aware there were actually people out there regardless of language who weren't catching and surfacing 500s in a straightforward fashion to the user.
Even their blog has such dead links. I just happened to notice that other URLs included the year, so I tracked that one down to see if that’s all what was needed.
Of course, forgetting about that little backwards compatibility is easy, especially considering it’s a personal blog and they likely have other personal things to worry about. I was just amused by the irony in context. I otherwise appreciated the read. :)
I should be able to find it. It was an aggregate post from 2014 titled something like “stuff I wrote this year” which is how I found the year for the post in question.
Does anyone still remember the days when a certain browser would ignore what the server sent with a 404 page unless it was larger than 512 bytes? Yeah, I'm happy with the browser just showing what I send it without trying to second guess the content.
base64 inline your image with the HTML and you should be well past that threshold.
It's preferable to not make additional requests (like for an image) on an error page - in case the requested server is at fault - breaking the error page.
Fun fact: did you know you can inline an image without base64 encoding it? Use svg you can inline the markup using a data url without base64 encoding. This is how I do my favicons at simpatico[0]:
To me, none of this is surprising or undesirable - ie the browsers are doing the right thing. Content is there to be rendered, not hidden. Status codes are not there for the average end user.
This feels surprising for a minute until comes to mind all the little things that would be broken if browsers didn't behave that way.
Custom 404 pages to give the user a friendly explaination and further directions, 500 pages with the exception stack trace in our frameworks to debug the errors etc.
A status different from 200 rarely means there's nothing that could be displayed to the user.
I remember a talk years ago where someone had written an Nginx plugin that returned a random status code (from a list) for every request.
Normal users would never notice and could browse the site fine - but bots (and particularly vulnerability scanning tools) couldn't cope with it and would show all kinds of weird results and false positives/negatives.
security by obscurity only stops casual bots, and any determined bot would easily be able to ignore the status code and inspect the contents to get at what they wanted anyway.
And you run the risk of having a transparent proxy fail on your real users doing this too. It's why nobody does it.
This is the cause of a split in failure situations.
Failures fall into two often very distinct cases:
1. Failures the end-user is able to understand and in some circumstandes to fix themselves. Examples: (HTML) page not found, no connection, etc.
2. Failures the end-user is in no case able to fix; it's up to the programmer. Examples: Server misconfigured, missing media files on server, etc.
It never makes sense to display the full error messages in case 2. It suffices to hide the error and perhaps make it available in DevTools. Often a good way is: give a generic message, and because some failures are transient, tell the user to retry. Also it can make sense to add an error number so that the end-user can give support the error number.
So it is useful to let the browser be lenient with HTTP status codes except in some specific cases which the article does mention (HTTP status code 500 for JavaScript files, for example).
I think, this is a general design feature. The specs explicitly allow a possible document body. If the status doesn't affect the process of retrieving the requested document (like a redirect), a client is free and even expected to display the document body.
Having said that, if the status code is in the 4xx client error range, I'd wish that any document.title would be strictly ignored and browsers would always display the status code (together with the human readable error title) as the page title.
(I'm not sure there's any way to find the HTTP status code in a modern Firefox environment short of using web developer tools. It's not in places like 'Page Info' as far as I can see.)
I'm old enough to remember times before browsers showed 'friendly' error messages, and a 500 response from a server would display a '500 Server Error' message to the user. Users hated it. They'd panic and think they'd broken the website somehow. It was horrible from a support perspective, and if the user was new to the web it sometimes made them very anxious about using the web in the future.
Users have no business seeing error codes. Those are for devs. Hiding them away in devtools is a very good thing.
When did we stop building software for the "Power User" persona? I don't disagree that there are some (many?) people who start screaming and running in circles when they see an error code, but not every user is like that. You don't have to be a dev to care any the distinction between a system doing its job and silently failing. Why not have some indication that there's smoke coming out from the engine?
This sounds like inconsequential quibbling over terminology. There's nothing stopping a browser power user from opening up dev tools to look at error codes.
It's not inconsequential in my mind because as a power user I don't a-priori care about the site enough to have a reason to open the dev tools. What I'm missing is the indication that there even is a problem of some sort, and that if I wanted to see the problem details, I could open the dev tools.
In other words, as a power user, I want to know if the site has a "You problem", and the only explanation I fully accept for why the modern web doesn't notify users about website errors is that it allows companies to save on QA costs.
Their point I think is that often (to varying degrees), 'power user' things are less convenient to do or behind configuration options or menus and so on nowadays.
When did we stop building software for the "Power User" persona?
I think the change was very simple - we stopped bothering with middleground. "Power Users" were treated like "users, but a bit more", so we had 'users', 'power users', and 'developers'. All that happened is that we just accepted that power user can have the same access to tools as developers.
We didn't stop giving power users extra power. We gave power users more power.
Power users haven't become lazy. The middle ground for power users has disappeared. Now it's a split between "everything is so dumbed down and hidden behind fifteen layers of clicks" and "setting up and caring for your system is a second job in addition to your regular job".
I think overall the complaint is every type of experience. Including native apps. You can't simply dev tools inside of a native app. Even with Charles proxy or something you'd be grasping at straws trying to figure out what may be the actual issue (and at that point you probably can't work around it anyway)
Sometimes when I put my power user hat on I find myself thinking that the software I'm currently using is not meant for power users and instead I need to look for the alternatives. Now it's not just a few clicks away but I need to install some new type of software.
So the options for power users are still here, but they just aren't front and center as they used to as you said. This reminds me a little bit of the discussion around the iphone not being customizable and the response being that you have the option to just get an android phone instead.
At some point in the spectrum here one must become lazy when they can't be bothered to click on a few things or find an alternate product, and you become entitled when you demand power user features to become front and center when the vast majority won't ever need to use the features.
I've always had the opinion that it's possible to have a middle ground. User friendly defaults, the ability to dig deeper and the ability to make advanced features more readily accessible. It's not easy though, picking one or the other is definitely a lot easier.
On the flip side, how difficult is it to open dev tools, flip to the network tab, and look at your status code return(s) as a power user? As a power user, it never struck me as a high vertical.
The problem is, now I have to do this every time for shitty dumbed down apps.
Prime example: Twitter always responds "oops, something went wrong" even if the backend returns `{ error: "Video aspect ration is not allowed. Try 16:9" }`
Those "oopsie-doopsie, website made a poopsie" infantilizing error messages are just awful. Tell the user 1. specifically what went wrong, 2. what, if anything, they can do to correct, and 3. a token (like an error message) that could be useful for tech support or reporting a bug.
People's heads aren't going to explode if you treat them like functioning adults.
The meta conversation here is whether there was a decision to NOT give the user information on how to correct the problem - or if it was a process maturity, developer skill, or limited resources that caused the development to focus on the "happy path" only.
Dev tools of a browser are not what a power user focused browser would need. Think more about being able change keyboard shortcuts. Being able to execute small custom scripts that do stuff with tabs, windows, and pages. Yes I know browser plugins and bookmarklets exist.
But why do bookmarklets run with the security context of the currently opened page? I have one self-written bookmarklet to capture the page title and url into emacs for storing it there. Firefox asks me every time I click on that bookmarklet on a new origin (domain, protocol tuple) whether I want to allow that. With no option to avoid that. I have written this piece of code myself I want to use it to enhance my workflow. There is no need to treat it like any javascript hosted on a CDN, or on a Facebook server.
My day job is C++ app and driver code for rather complex systems yet when I open browser dev tools my eyes glaze over. There is plenty of middle ground of people who are technical but are not web or browser developers.
I’m not a web or browser developer, the vertical isn’t quite as high as “you need to be working in the web space to understand it.”
There’s a lot to look at in there, but there’s some usual suspects tabs that people look at the majority of the time they have dev tools open. And conversely some tabs that you probably only use in the web dev scene. I’d highly recommend perusing the network and storage tabs, for things like status codes and cookies, respectively. As I mentioned, the vertical is nowhere near as high as you’re saying, you’ll figure it out if you look at it more.
> We didn't stop giving power users extra power. We gave power users more power.
No, most software today is designed for the use case that you have never seen the software before. That is implicitly enforced by the way most companies do A/B testing. The experiments show a new part of the UI to an unsuspecting user without any upfront knowledge that they are part of an experiment. Therefore the variant that has the lowest hurdle for the most common case of the most common user is optimized. So it is basically ignored that people tend to learn how to use their tools.
Learning to learn your tools is even made harder by constantly changing UIs. Reading documentation, following tutorial, watching introduction videos is basically useless for a software that will change whenever a product manager needs to complete an increment for his KPIs.
I'm pretty sure A/B testing has become a cult whose rituals are often practiced in a way that leads people away from meaningful or productive outcomes.
Is there anywhere else you've found where people are talking about this (either from a perspective of how to do it better or what else to do instead)?
> No, most software today is designed for the use case that you have never seen the software before.
Yep, it's fun when you go to a site where you have a log in but it expired and have to search for the tiny 'sign in' button that's mostly covered by the sign up form.
Much of my web experience is broken by default due to blocking Google or occasionally Microsoft ad analytic data. Many flows expect these to load even if it is not necessary for the functioning of the site. Many other sites break just due to strict enforcement of anti-cross-site tracking.
I'm not just talking about ad supported sites, although I guess you could say that Google Drive is indirectly ad supported.
Since I do most of my ad blocking at the network layer rather than in my browser, it's not always obvious to me as the user whether it was a "my blocking broke the site" error or a "The site is broken" error.
I don't see how this is related to an error code. Most of the time, if you get a non-200, the website is broken in some way and it's not your problem to fix. If it is (because you develop an extension, for example), it's easy enough to open dev tools. But for the most part, status codes aren't relevant even for power users, as you have no idea whether the page handles the error or is silently failing.
I didn't agree with their conclusion. But the quoted part seemed correct. Some response codes are much more common than others. Redirects are followed by some other code unless the web site is broken in some way. 410 means the web site removed something. Most of the time 404 means the same. Or a link was generated incorrectly.
OPs assertion checks out. Users won't see a 1X or a 3X. 2Xs are the success case. 4Xs are usually caused by an error in the website that the user didn't define but was served them. The exception is bad data formatting that the UI has probably flagged to them so they never send it to get the 4X. 5Xs are clearly a break in the website.
Related: the boot scroll. most of the time the scroll of boot messages is harmless and when the system fails to boot it is very very useful to see where. yet the design types hated it. and now no desktop orientated OS shows a boot scroll, opting for a near useless spinner instead.
Opinion: I quite like the scroll, I think it comforting to see what the machine is doing. I think this is why sim city put a fake one in their loader(reticulating splines anyone). I wonder if the sim city messages tied into actual load events and could be used by the programmers to debug the loader. I think the later ones were random, but 2000 might of had an order to it.
The boot scroll was/is actively harmful in that it requires process-of-elimination troubleshooting to recognize deviations from a "normal" boot process.
The individual subsystems should be able to recognize their correct state and output a clear diagnostic when they are not in that state. I shouldn't have to step back through e.g. several broken services to find out my second ethernet port didn't initialize.
Isn't the power user served perfectly fine with the devtools? I mean if a website breaks a normal user is going to leave it the power user will open devtools?
My current pet example for the trend of hiding more and more details from users is an issue I recently had with Doordash.
I was trying to place an order, and it kept failing with a red banner stating "something went wrong" (I'm paraphrasing as I don't recall the exact verbage, but it was one of those completely worthless error messages)
Pop open dev tools ... the server is returning something about a graphql error.
Support had no idea what was wrong.
The problem ended up being that my saved credit card had expired. For fuck's sake, that is a user-actionable error; tell me what the problem is. At least tell me it was a payment problem, since that's probably all the payment processor told you.
That isn't true, laziness will punch straight through a tight definition of error code handling.
After all if you have three API layers realizing in this situation the second layer isn't forwarding that error code because it erroneously thought it was one you hide behind a generic one is pretty common.
There must be a middle ground between "Something went wrong, please try again later :)" and "TypeError: Cannot read property 'submit' of null" when performing an action.
I sometimes hear the "best of both worlds" is something like logging all errors while showing optimistic errors to the users on frontend. This is somewhat fine for errors that happen on the backend, but catching browser errors is tricky because extensions can throw errors. On top of that a user might not be comfortable with you collecting errors that happen in their browser.
Those are two ends of the spectrum of how to handle unknown errors, but ignore the other axis: known errors. The UI displaying a red text field saying "field whatever is required to continue" is just as much an error message, but it's clearly actionable. There are lots of reasonably actionable error messages in all varieties of UIs for expected error cases.
I don't know that there's a lot of useful middle ground between your two examples though. By definition, a UI can't really give actionable advice on how to fix an error that it isn't programmed to expect.
Yeah this problem is a little more complicated than what I mentioned. By all means map known errors, but does the fallback really need to be "something went wrong?"
It was a bit of a rhetorical statement (or at least in my mind it was). Like how about "Something went wrong (see details)" or something to that effect?
In my work experience some people are really dogmatic about the idea of not showing any sort of error messages to users whatsoever.
In my work experience, users will complain about any sort of message. We recently got a request to change a message of "OK" to something more detailed. What more do you want than a message telling you that the thing you were trying to do succeeded?
So I'm very sympathetic to people arguing against showing error messages.
Yes, the user should see the former, and the application should log the latter.
The user probably can't do anything about a null reference, so there's not a lot of benefit in providing this level of detail, and for most users it obscures the bigger point that "something went wrong."
5xx means the server messed up, if the user should've done something different you'd see a 4xx error.
A good web server validates the user input, throws a 4xx error if the input is bad for the current state, and if something still goes wrong (which is a server bug) the 5xx range becomes appropriate.
400 is a client error. 500 is server error. A server error induced by a client action (e.g. triggering an unexpected exception) is still a server error.
If a user is using your web application normally and ends up with an error, it is an application error. Be it a 401, 403, validation error, 500, 429, whatever, it is not an actual user fault but it is a problem within the application.
Once you have this realization, what's the advantage of showing the proper error code to the user? Whatever it is, it's not in his power to fix it
Because application errors are not one-size-fits-all. Sometimes it's because of some specific flow being broken. Sometimes it's "the site is down". Sometimes it's a "there's an error condition that needs to be bubbled up to the user". And sometimes it's a poor internet connection being mishandled.
While code fixes are not in their power to do, changing their behavior, or waiting for a better internet connection (i.e. "something went wrong" actually means "go log in to the hotel wifi") are things in their power.
>Once you have this realization, what's the advantage of showing the proper error code to the user?
Have you ever done end user support? Having a moderate amount of detail like an HTTP response code saves tons of time and headaches when a user calls in.
And some of the specific codes you mentioned (401, 403, and 429 for example) actually do give a power user actionable information. They can know that there's something wrong with their login credentials or permissions, or that they are making too many requests too quickly and need to slow down or wait to stop being rate limited. And knowing that it's some kind of 500 error lets a power user know "Ok, this probably isn't an issue on my end" which helps them stop worrying that it's something they're doing wrong or something wrong with their system.
Again, you are underestimating users. They will work around errors and can use some quite hideously broken systems to get what they need done, without any support at all sometimes. Hiding error messages just makes that a much more frustrating process. (put another way, the user probably can't fix the error occurring if they just do the exact same thing again, but they can often find another way to do what they want without triggering the error, and for this it helps to know what the error actually is)
Users are told what's wrong. They get a friendly "Page not found" or "Server error" page. They're not denied access to the cryptic error code that means nothing to them.
Cryptic error codes that mean nothing to a layperson can result in online discussion in community support where users or devs can actually help each other. Or they might just glean enough information to work around the problem themselves. Zero information is not empowering.
Those are usually structured HRESULT values, Win32 error codes, and NTSTATUS values.
So in a way, they are already "elaborating" the type of error - as well as a single 32-bit integer in C can "elaborate" over an error, that is, not a lot.
For all their faults dotnet and java make it really easy to not mangle up the stack trace.
Absolutely true. Especially now that the server is more likely than ever to have an in-browser application as the actual client. That client is the interface to the user and it should be responsible for communication the issue.
I draw the line at nice urls though, I think that's valuable to the client app and the user. At the very least, bookmarks work. Even with all the other state than can exist, it's a solid and useful reference point.
Also firing a second request would break restful behavior and could wind up really messing stuff up worse. Maybe it places an order twice? Who knows. Not a good idea.
Those barebones ‘XXX Error’ pages are sent from the server and rendered in the browser just like the post talks about. Browsers have always handled the html returned with the error code in the same way (by showing it to the user). The only difference from the old days is that now sites show a nicer page instead of using the default barebones error pages.
What if the error is a problem the user can actually address and continue using the service? I don't think we should stop trying to make useful error messages because some people are completely helpless.
>Users have no business seeing error codes. Those are for devs. Hiding them away in devtools is a very good thing.
I can't say I agree. That would be a good idea in a world where users never encountered errors in normal circumstances, but in fact computers don't work very well and users encounter errors on a regular basis. Using computers is a skill. It takes study. You can either pretend that it doesn't, giving users something underpowered that is going to break anyway, or acknowledge that computers are complicated, and build tools and resources to help users navigate them. And users should recognize it as folly to try to use the most complicated tools on the planet today without any understanding of how they work.
This doesn't really apply to HTTP status codes. They're largely useless. It does apply to the way my Macintosh told me of a misconfiguration after I reinstalled the operating system. Somehow the people at Apple thought an error code and a brief description would be scary, so they opted for this absolutely terrifying icon instead:
>Somehow the people at Apple thought an error code and a brief description would be scary, so they opted for this absolutely terrifying icon instead
This is why interfaces made by programmers tend to be impossible to use. Our minds simply work differently than normal people. In the 99% case, that icon will tell a user precisely the same information as any kind of detailed error log, which is "Oh no, something is broken, I should go to the Apple store."
I mean ... cars have had different error lights for decades. Doesn't seem like that much of a stretch that people would be able to use a little critical thinking when looking at computer error messages too.
In my experience, people hate when cars just flash a "check engine" light. It is impossible to tell the difference between "probably OK but get it looked at", "might leave you stranded", and "might literally explode".
Cars show error codes every few months or years and there's nothing the average driver can do to fix them. Computers show errors on a daily basis and most of them are trivially fixable.
The parent post says "different error lights" and that might be indicative of experience with European cars. In, say, an Audi, there are 3 or 4 different subsystem lights, with yellow indicating a "get it looked at" issue and red a "stop now" problem. And "might literally explode" usually results in an engine shutdown.
> Computers show errors on a daily basis and most of them are trivially fixable
As they say, "citation required". How do I fix my Windows Update 0x80070422 error? (And yeah, I know, don't use Windows -- but I have plenty of *ix examples as well...)
I despise that check engine light for exactly that reason. It would be much more helpful if the car also displayed the error code that made the light turn on. Then I'd know how urgent the issue is and whether I need to take it to the shop.
The light tells you that already: take it to the shop.
The annoying part for folks used to having control (eg power users) is that someone else decided that that was enough info for drivers. If you want the power-user car UI, you'll need to get out of the driver's seat and put on your mechanic hat. (Like sibling comment who purchased an ODBC reader.)
> The light tells you that already: take it to the shop.
That's not enough information. At a minimum, there should be a way to distinguish between "you should make an appointment with a mechanic at your earliest convenience" and "pull over right now and call a tow truck, or you'll have to completely replace your engine and transmission".
> The light tells you that already: take it to the shop.
No, it doesn't. The light comes on for routine maintenance that doesn't require a shop, and it comes on for things that might require a shop, but not urgently as well as things that are urgent.
I did get an ODBC reader just for this reason. But I shouldn't have had to. The car should just give me the code(s) itself.
> The annoying part for folks used to having control (eg power users) is that someone else decided that that was enough info for drivers.
I'm not annoyed at not having control. I'm annoyed that whoever decided that a single light gave enough information was incorrect.
And that's a flaw in the design of modern vehicles. The vague error messages give mechanics lots of leeway on screwing over people, much like computer repair shops will charge exorbitantly to the person who doesn't understand computers.
Transparent error messages are more useful, and gatekeeping drivers with a connector and a list of codes should be considered unethical. Too many industries are trying to sell you something, but not let you make it yours or let you understand it. Before long, the value proposition will fall.
> In my experience, people hate when cars just flash a "check engine" light. It is impossible to tell the difference between "probably OK but get it looked at", "might leave you stranded", and "might literally explode".
This is why I bought one of those OBD reader things so I can have more of an idea of what is actually going on. Not that I really understand anything that it says, I’m pretty clueless when it comes to car stuff, but it sure makes me feel better
The only time I ever got a check engine warning, the problem was obvious from the physical symptoms: cylinder misfiring. Well, I didn’t know what that was when it started happening, but now I do. Drove it to the mechanic and they replaced the spark plugs
>Doesn't seem like that much of a stretch that people would be able to use a little critical thinking when looking at computer error messages too.
Users' critical thinking skills can be fine, but sometimes they choose not to apply them for things they don't want to think about. That's totally normal if computers are outside their purview or they just want technology to work.
No small amount of people just take their car to the shop and don't try to interpret the errors. Knowing when to make your users think comes with the product territory and knowing your audience, and also considering "how important is surfacing that error detail, really?"
If you want the dirty secret for why, it's because we can be lazy about things we don't care about and/or critically thinking about everything is exhausting and sometimes you have more important things to do. They just want it fixed.
Cars are actually a good example of how errors should work. Errors should give appropriate information to diagnose and solve the problem to the stakeholders.
So a car may have different lights/states from "low fuel", "tire pressure", "door ajar" - to "service soon" to "failure imminent". These are all meant as calls to action by a typical driver, including potentially having them escalate to a mechanic/service center.
It is the mechanic can read off the status codes of the car computer to help further diagnose the issue.
A 401 in a browser indicates how the _browser_ can react to insufficient authentication, via the instructions in WWW-Authenticate headers.
The majority of status codes provide very little instruction to the browser, and provide even less to the end user. "400 Bad request" doesn't include instructions on how the browser can fix the query or form data being submitted, nor is there a process to inform the originator that they are linking to a location incorrectly. To the end user, a 400 error is even more worthless - there is nothing about a 400 that gives instructions on how to get the problem repaired.
The trend for development is to define errors which describe each failure case and to delegate those errors up. A robust system however needs to think about failure cases holistically and along with their recovery steps. Once you do this you typically have significantly fewer errors, because you have identified the appropriate recovery steps.
> in fact computers don't work very well and users encounter errors on a regular basis. Using computers is a skill. It takes study.
I think what's been lost -- or perhaps never been gained -- is an art of dual tiering error condition messaging.
Highest visibility messaging should be the simple & for the most general audience: "You Gave us Bad Information, here's how to fix it" for cases where that applies, with more information available for training users if they want it.
When it's an application or systems failure: "Something went wrong on our end, not your fault" should be the high visibility message. Then maybe "here's a request ID, you can contact this support channel about it if the problem persists". Then somewhere low visibility "here's some detail about what's going on under the hood if you want to look."
This is part of a general sin in product / UX as far as I can tell: the "don't make me think" mantra became something itself people stopped thinking about and transformed effectively into "don't LET me think."
It seems you're advocating for error messages which I think many would agree with, but the comment you're responding to was proposing that error codes have no place being shown to users. I would generally agree with hiding codes. They're generally meaningless and really intended for devs or automation.
> Somehow the people at Apple thought an error code and a brief description would be scary, so they opted for this absolutely terrifying icon instead
That error is the boot firmware telling you it can’t find a bootable OS. It doesn’t know what language you speak, and would an error code really be helpful?
If you’re knowledgeable enough to know what the error codes mean, you would know that cmd-V gives you verbose logging.
>If you’re knowledgeable enough to know what the error codes mean, you would know that cmd-V gives you verbose logging.
This is exactly the sort of thing I'm talking about. You assume that anyone who doesn't know every hidden Macintosh hotkey is so ignorant of computers they won't even know how to look up an error code. If there are magic hotkeys that modify the boot sequence, that might be some information I would like to know when trying to boot my computer! Why not display those hotkeys during the boot sequence like a normal OS?
This is an opinion that, on a personal preference level, I share. It's not, however, a universal truth. An optimally useful computer should be a human interface to information or control of something. The best computer is one that interprets a messy human command, produces the information or action that the human actually wanted, and requires no training at all to use.
Such a machine would be anathema to me, personally, but it would be objectively the best possible general purpose computing device.
I disagree. I think users should be aware of any breakage up front, and center. We encourage drivers to recognize warning signs in the operation of their vehicles; we should do the same with browsers. Hiding information from the user is not ethical.
Then again, I also think people should be taught better than to hop on the Web without any training or knowledge. Computers and illiteracy go together about as well as books go with illiteracy. It takes effort to be computer literate, and hiding the information will make that journey to literacy more daunting than it needs to be.
My personal inclinations agree with yours, I think. I prefer as much detail as possible up front. Which is why I hate the vagueness of my dashboard's "check engine" light*. However, I bet automakers do that not just so the display is cheaper/simpler, but because most drivers are not interested in anything more detailed (or scary).
* Which for me has almost always just meant some oil change "timer" was up, not even that any meter detected my oil was wearing out.
Years ago, many decisions to hide error details were a cargo cult reaction to CVE-2012-4929. To review, CVE-2012-4929 works like this:
1. the attacker can see (but not decrypt) the victim's TLS traffic to example.com
2. an attacker-controlled website makes the victim send many different invalid requests to example.com, each of which gets an error message
3. some data in each request is attacker-controlled, but authentication data in headers is filled in by the victim's browser
4. example.com compresses response data before encrypting it
5. because repetitions affect compression, the response size is smallest when the authentication data matches part of the attacker-controlled data
6. after enough requests, the attacker knows the authentication data to login to example.com as the victim
One workaround for CVE-2012-4929 was to set up the server so that an error message never depended on the request data. Before CVE-2012-4929 was announced, people thought it was sufficient to sanitize the error message (i.e., avoid XSS) but CVE-2012-4929 prompted a shift toward producing exactly the same error message for all invalid requests. (Not sure, but I think this was the original motivation for Google's famous "That's an error. That's all we know." messages.)
There were better CVE-2012-4929 defenses later, but the cargo cult had already formed. (Some subset of) a generation of developers believed that customized error messages were Very Bad because they enabled account takeover.
I've thought about alternative dashboards as an option, that show rpm, piston firing stats, or other small details that, when looked at in aggregate, can diagnose a lot of consumer-serviceable issues.
Or you can take the route that a former client took: Return 200 OK http status code and just print "500" in the response body. Took me a few minutes to figure out why the monitoring kept insisting that everything was OK when my browser kept showing me "500".
> It's a convention (and a useful one) that the HTML served for a web server's error pages will include the HTTP status code in the text (and often the <title> as well). But it's only a convention and it can be violated, both accidentally and deliberately (both in omitting the status code and listing the wrong one). If it is violated, you probably won't notice for a while (if ever).
A malicious server can just as easily send the wrong status code, as well as listing the wrong status code in the accompanying html - so if the browser did show the real status code more prominently to the user, that wouldn't actually help in such a case, or would it?
This is the web equivalent of “no user serviceable parts inside”.
Watch Joe Average use a computer. If he’s shown an error either he recoils as if he’s physically broken it (or the website) or repeatedly just performs the same action again and again like a chicken pecking at a corn dispenser, or finally mashes the keyboard with his fists and slams the laptop shut in frustration.
The days of a bespectacled web user, thoughtfully musing over an error message, while fiddling with a self-propelling pencil, sat at a Sun/SGI/HP/IBM X11 session are long gone.
Web browsers handle the status code correctly by displaying the error in the response body. 500 isn't for end users - it is for web crawlers and caching proxies.
The author is wrong, browser behaviour does change significantly in one major way: errors are not cached.
Or much more importantly, errors incorrectly returned with 200/OK success codes are cached, semi-permanently breaking your site.
If you've get helpdesk staff telling customers to "clear their browser cache", this is one common reason why this "works" as a fix.
Please, I beg you: stop being "nice". Stop catching exceptions and dropping them on the floor! Let them bubble up to the web framework pipeline so that an error code is sent.
Your CDN will thank you. Browser caches will thank you. Corporate proxy servers will thank you. Application monitoring tools will thank you. Load balancers will thank you.
I kid, I kid. None of those will send you thanks in an email. Instead, they'll work tirelessly in silence to deliver your application as intended, instead of holding on to transient errors for days on end and upsetting your users.
Also: search engines. I spent a good chunk of a month fixing an app initially developed with this mindset. Immense value delivered just by making things work as they should've from the beginning.
Letting an uncaught exception error reach the user is generally bad. It risks exposing secrets / confidential information to the user and any returned client side secrets risk getting into intermediary caches.
The biggest risk is the user input being returned in the response creating an XSS (cross site scripting) risk. This is a very common source of reflected XSS vulnerabilities.
You should always catch exceptions like this so you can at the very least sanitize them for XSS. This is already built in to some frameworks. If you are using something that doesn't you need to do it yourself and it's probably easier to just strip it all in production, you just need to make sure you are still setting an appropriate status code.
Who said anything about letting exceptions reaching the users!?
The exception needs to bubble up to the request pipeline, which will set an integer error code, and then... redirect to a generic "sorry we broke" error page.
Showing the full exception stack trace and other sensitive bits and pieces is for local debug mode, not for production.
I think it’s cute you think most developers let exceptions rise.
Most developers I notice just catch the error right away and make the function return something non-sensible like a 0 for a string value function.
Slightly better developers just let the exceptions bubble.
The rare breed looks at what exceptions are being thrown, decides which ones to handle at which stack level, and repackages them as needed when the error cannot be handled that deep in that stack due to a lack of context. Then they write framework-level exception handlers for errors that rise to the top because they cannot be corrected at a higher stack level to give users specific error messages with user-correctable actions without revealing anything sensitive. “Your image is too small, wanker.”
In the first line of every function. It's tells the Interpreter:
"Shhhh, it's fine. Just ignore errors. Division by zero? No worries. It's Fiiiiine. Try to access inexistent index of an array? Who cares, it's Friday!"
Just because they rendered the text doesn't mean they've ignored the status code.
There can be a lot of other stuff going on behind the scenes that are happening differently due to this code.
A 503 with a Retry-After header is a good example, although it has limited browser support, but in theory it will reload the page after the timeout.
There are different caching/storing rules with different status codes, they may also disable certain features, eg if you have been loading a page with an error you might find the auto complete feature in the URL bar doesn't work. I often find this is really annoying when building something new and haven't got it quite working, I keep needing the full URL, where as if it had just once given me a 200 I could just type a few letters and it would come up, but it probably far more useful that auto complete doesn't get polluted with mistyped URLs and broken websites.
Page reloads doesn't seem to be an anticipated or suggested feature for this header, irrespective of error code. Communicating API rate-limiting (429 Too Many Requests) or temporary downtime (503 Service Unavailable) to other services and bots seems to be it's most use.
> if you respond to a request for a web page with a HTTP 200, 4xx, or 5xx code outside of these specific ones and some HTML, almost all browsers will display the HTML to the user
Chrome outright refuses to show the HTML of a 500 response in favor of its own dinosaur animation or some garbage, or did that change?
Once upon a time I wrote a feature request for the Chrome extension team to allow an extension to change the response code of a request. This would be a real boon to testers wanting to see the behavior of the browser under those conditions without having to fiddle with the server. But the Chrome team closed it as unneccessary or something.
Browsers are just shit user interfaces. They've never prioritized the user experience, nor actually integrated good solutions to common status problems. Designers even actively avoid common widgets because they're so bad.
Every once in a while they remove widely used functionality from the UI or bury it behind a lot of other crap, so someone has to invent an extension to bring it back. It's terrible.
All the alternatives have varying degrees of suckitude, and there's no way to just make an alternative browser without like $1.5 million dollars and two years of development.
211 comments
[ 3.1 ms ] story [ 345 ms ] threadChris says that the loading of sub-resources is a different matter. Well, the most common silent failure I have is not due to status codes per se, but because of my DNS-based adblocker, many sub-resources fail to load (GET or POST) with a network error (TCP RST). Unless a blocked domain corresponds to the front page I visit in a URL, the unavailable resource represents a silent failure, and I have foolishly contacted Support desks multiple times because my own use of the adblocker caused a silent failure that was difficult to diagnose.
In fact, I now have no way of knowing what web apps are like without an adblocker. Because all my devices use the same configuration, and it's non-trivial to disable it, I simply don't know what I am missing. Indeed, in the case of one web app which I've used as a PWA, it was simply missing features that I knew should have been there, and whitelisting enough domain names caused those features to re-appear.
I will just leave you with the most adorable 404 page anyone has ever seen: https://diopitt.org/pray/amen
pihole as cache, with the router as its upstream, with NextDNS as the router's dns server
They have a feature where if you're a free user, and you exceed your query quota for the month, they turn off all features and it acts like a normal resolver.
For some reason, there is no access to such a setting to do it manually, and I am a subscriber now, too.
There are profiles that can be configured separately, but even just to activate an alternate profile, one must reconfigure the DNS settings on the devices.
Is this not intended behavior? Were you not expecting ads to be silently removed?
But unless you open the dev tools' network tab, you don't know about that request failing.
My ad blocker returns "0.0.0.0" for A records, which in practice means attempts to connect to 127.0.0.1, which isn't running a server of any kind on port 443/tcp or 80/tcp. So a standards-compliant client would really hang awhile, or hold rendering, until several connects have been attempted and they all failed.
In the context of your comment, I was amused by how my own ad-blocker failed to properly show the (image on the) 404 page, since it is loaded from a different domain :D
This is exactly why I do not use a DNS-based ad blocking solution (it’s trivial to disable uBlock Origin and refresh if something feels broken).
In what way? Do you mean not feasible or just lazily coded?
See also Richard I. Cook's "How Complex Systems Fail": <https://how.complexsystems.fail/>
(Latter is an HN perennial, with 55 sumbissions presently: <https://hn.algolia.com/?q=how%20complex%20systems%20fail>. Most recent 10 months ago, so not quite ready for a re-up: <https://news.ycombinator.com/item?id=32895812>.)
https://deirdre.net/2014/programming-sucks-why-i-quit/
The Internet Archive has a copy as well: <https://web.archive.org/web/20200922230737/https://deirdre.n...>
Of course, forgetting about that little backwards compatibility is easy, especially considering it’s a personal blog and they likely have other personal things to worry about. I was just amused by the irony in context. I otherwise appreciated the read. :)
It's preferable to not make additional requests (like for an image) on an error page - in case the requested server is at fault - breaking the error page.
0 - https://simpatico.io/svg.md
Thanks for the tip, and the many examples on your site!
And if the server has broken so badly it can't send out that image, then I have much bigger worries than an ugly 404 page.
And then Oracle shipped the AskBar into the Java installers.
https://stackoverflow.com/questions/8338427/i-created-a-cust...
Custom 404 pages to give the user a friendly explaination and further directions, 500 pages with the exception stack trace in our frameworks to debug the errors etc.
A status different from 200 rarely means there's nothing that could be displayed to the user.
Normal users would never notice and could browse the site fine - but bots (and particularly vulnerability scanning tools) couldn't cope with it and would show all kinds of weird results and false positives/negatives.
And you run the risk of having a transparent proxy fail on your real users doing this too. It's why nobody does it.
Casual bots is what 95% of website operators have to deal with, blocking them is still a win.
Same reason people move ssh ports around. Of course it doesn't add security if you're targeted, but it makes casual bruteforce bots go away.
Call that log hygiene if you really object to the security aspect.
Failures fall into two often very distinct cases:
1. Failures the end-user is able to understand and in some circumstandes to fix themselves. Examples: (HTML) page not found, no connection, etc.
2. Failures the end-user is in no case able to fix; it's up to the programmer. Examples: Server misconfigured, missing media files on server, etc.
It never makes sense to display the full error messages in case 2. It suffices to hide the error and perhaps make it available in DevTools. Often a good way is: give a generic message, and because some failures are transient, tell the user to retry. Also it can make sense to add an error number so that the end-user can give support the error number.
So it is useful to let the browser be lenient with HTTP status codes except in some specific cases which the article does mention (HTTP status code 500 for JavaScript files, for example).
Having said that, if the status code is in the 4xx client error range, I'd wish that any document.title would be strictly ignored and browsers would always display the status code (together with the human readable error title) as the page title.
I'm old enough to remember times before browsers showed 'friendly' error messages, and a 500 response from a server would display a '500 Server Error' message to the user. Users hated it. They'd panic and think they'd broken the website somehow. It was horrible from a support perspective, and if the user was new to the web it sometimes made them very anxious about using the web in the future.
Users have no business seeing error codes. Those are for devs. Hiding them away in devtools is a very good thing.
https://developer.chrome.com/docs/devtools/open/#auto
I think we just have fight for poweruser options to be available via APIs and support the add-on ecosystem.
In other words, as a power user, I want to know if the site has a "You problem", and the only explanation I fully accept for why the modern web doesn't notify users about website errors is that it allows companies to save on QA costs.
I think the change was very simple - we stopped bothering with middleground. "Power Users" were treated like "users, but a bit more", so we had 'users', 'power users', and 'developers'. All that happened is that we just accepted that power user can have the same access to tools as developers.
We didn't stop giving power users extra power. We gave power users more power.
I think overall the complaint is every type of experience. Including native apps. You can't simply dev tools inside of a native app. Even with Charles proxy or something you'd be grasping at straws trying to figure out what may be the actual issue (and at that point you probably can't work around it anyway)
So the options for power users are still here, but they just aren't front and center as they used to as you said. This reminds me a little bit of the discussion around the iphone not being customizable and the response being that you have the option to just get an android phone instead.
At some point in the spectrum here one must become lazy when they can't be bothered to click on a few things or find an alternate product, and you become entitled when you demand power user features to become front and center when the vast majority won't ever need to use the features.
I've always had the opinion that it's possible to have a middle ground. User friendly defaults, the ability to dig deeper and the ability to make advanced features more readily accessible. It's not easy though, picking one or the other is definitely a lot easier.
Prime example: Twitter always responds "oops, something went wrong" even if the backend returns `{ error: "Video aspect ration is not allowed. Try 16:9" }`
People's heads aren't going to explode if you treat them like functioning adults.
But why do bookmarklets run with the security context of the currently opened page? I have one self-written bookmarklet to capture the page title and url into emacs for storing it there. Firefox asks me every time I click on that bookmarklet on a new origin (domain, protocol tuple) whether I want to allow that. With no option to avoid that. I have written this piece of code myself I want to use it to enhance my workflow. There is no need to treat it like any javascript hosted on a CDN, or on a Facebook server.
My day job is C++ app and driver code for rather complex systems yet when I open browser dev tools my eyes glaze over. There is plenty of middle ground of people who are technical but are not web or browser developers.
There’s a lot to look at in there, but there’s some usual suspects tabs that people look at the majority of the time they have dev tools open. And conversely some tabs that you probably only use in the web dev scene. I’d highly recommend perusing the network and storage tabs, for things like status codes and cookies, respectively. As I mentioned, the vertical is nowhere near as high as you’re saying, you’ll figure it out if you look at it more.
I don't think we did. The trend in the past few years is to dumb down all tools, especially UI tools, to the lowest common denominator.
No, most software today is designed for the use case that you have never seen the software before. That is implicitly enforced by the way most companies do A/B testing. The experiments show a new part of the UI to an unsuspecting user without any upfront knowledge that they are part of an experiment. Therefore the variant that has the lowest hurdle for the most common case of the most common user is optimized. So it is basically ignored that people tend to learn how to use their tools.
Learning to learn your tools is even made harder by constantly changing UIs. Reading documentation, following tutorial, watching introduction videos is basically useless for a software that will change whenever a product manager needs to complete an increment for his KPIs.
I'm pretty sure A/B testing has become a cult whose rituals are often practiced in a way that leads people away from meaningful or productive outcomes.
Is there anywhere else you've found where people are talking about this (either from a perspective of how to do it better or what else to do instead)?
Yep, it's fun when you go to a site where you have a log in but it expired and have to search for the tiny 'sign in' button that's mostly covered by the sign up form.
At second; it would likely mean many folks lacking in other skills, unbalancing what little we have in the society of work.
At third: include all the error detail you like, simply put it behind a "click here for more details" side door.
What?
The moment they(i mean we) started blocking ads I think.
I'm not just talking about ad supported sites, although I guess you could say that Google Drive is indirectly ad supported.
Since I do most of my ad blocking at the network layer rather than in my browser, it's not always obvious to me as the user whether it was a "my blocking broke the site" error or a "The site is broken" error.
That's completely wrong.
1xx codes are all INFORMATIONAL (usually used for switching protocols).
2xx codes are all SUCCESS.
3xx codes are all REDIRECTs.
4xx codes are all CLIENT ERROR.
Only 5xx codes are SERVER ERROR.
See https://datatracker.ietf.org/doc/html/rfc7231#section-6
1xx you do not care
2xx you are fine and do not care
3xx you are redirected and do not care
4xx crap, the client is wrong, you cannot do anything because the app is wrong
5xx crap, the server is wrong and you cannot do anything either.
"You hit a problem, it was reported to the devs, sorry. Try later" is the only reasonable message for normal users
That’s pretty power user friendly.
Opinion: I quite like the scroll, I think it comforting to see what the machine is doing. I think this is why sim city put a fake one in their loader(reticulating splines anyone). I wonder if the sim city messages tied into actual load events and could be used by the programmers to debug the loader. I think the later ones were random, but 2000 might of had an order to it.
The individual subsystems should be able to recognize their correct state and output a clear diagnostic when they are not in that state. I shouldn't have to step back through e.g. several broken services to find out my second ethernet port didn't initialize.
It's not a big deal for a power user to hit F12 then click the network tab...
1996 or 1997. I can't narrow it down further.
Shortly after that, they actively became hostile to power users. Just play with your dumb little consumer appliance like you're supposed to.
I was trying to place an order, and it kept failing with a red banner stating "something went wrong" (I'm paraphrasing as I don't recall the exact verbage, but it was one of those completely worthless error messages)
Pop open dev tools ... the server is returning something about a graphql error.
Support had no idea what was wrong.
The problem ended up being that my saved credit card had expired. For fuck's sake, that is a user-actionable error; tell me what the problem is. At least tell me it was a payment problem, since that's probably all the payment processor told you.
After all if you have three API layers realizing in this situation the second layer isn't forwarding that error code because it erroneously thought it was one you hide behind a generic one is pretty common.
I drive a car and only care about the speed, how far I can drive and to be warned that I have to stop if something is wrong.
I do not care about the temperature of the oil or water, about the tension on the thffr which powers the louhguh or why zgfnkvgv failed.
I know that if something goes wrong I will call the road assistance number.
If someone wants to learn more there is the hidden bus they can plug into, aka Dev Tools For Cars
I sometimes hear the "best of both worlds" is something like logging all errors while showing optimistic errors to the users on frontend. This is somewhat fine for errors that happen on the backend, but catching browser errors is tricky because extensions can throw errors. On top of that a user might not be comfortable with you collecting errors that happen in their browser.
"TypeError: Cannot read property 'submit' of null" is cheap (just render whatever error you get).
Anything else is expensive, and probably doesn't gain you anything.
I don't know that there's a lot of useful middle ground between your two examples though. By definition, a UI can't really give actionable advice on how to fix an error that it isn't programmed to expect.
It was a bit of a rhetorical statement (or at least in my mind it was). Like how about "Something went wrong (see details)" or something to that effect?
In my work experience some people are really dogmatic about the idea of not showing any sort of error messages to users whatsoever.
So I'm very sympathetic to people arguing against showing error messages.
The user probably can't do anything about a null reference, so there's not a lot of benefit in providing this level of detail, and for most users it obscures the bigger point that "something went wrong."
A good web server validates the user input, throws a 4xx error if the input is bad for the current state, and if something still goes wrong (which is a server bug) the 5xx range becomes appropriate.
Users and client software cannot (or rather, should never) be held responsible for 500 error codes, which "user breaks the server" implies.
Ah, yes, I love remote troubleshooting.
"What does the site says?"
"Hell I know but there are funny badgers singing about mushrooms!"
More so, problem maybe somewhere else so S. wouldn't even help here
People like you are the reason users cannot work a file system, download an image, or even read a short text message. You retard the users' progress.
Once you have this realization, what's the advantage of showing the proper error code to the user? Whatever it is, it's not in his power to fix it
While code fixes are not in their power to do, changing their behavior, or waiting for a better internet connection (i.e. "something went wrong" actually means "go log in to the hotel wifi") are things in their power.
Have you ever done end user support? Having a moderate amount of detail like an HTTP response code saves tons of time and headaches when a user calls in.
And some of the specific codes you mentioned (401, 403, and 429 for example) actually do give a power user actionable information. They can know that there's something wrong with their login credentials or permissions, or that they are making too many requests too quickly and need to slow down or wait to stop being rate limited. And knowing that it's some kind of 500 error lets a power user know "Ok, this probably isn't an issue on my end" which helps them stop worrying that it's something they're doing wrong or something wrong with their system.
This is an Anti-pattern called mushroom management (keeping users in the dark).
Not telling users what went wrong is just plain wrong. Breaking the termomether to hide fever.
When you get an error message you can at least google it, or make a ticket.
Something happened
So in a way, they are already "elaborating" the type of error - as well as a single 32-bit integer in C can "elaborate" over an error, that is, not a lot.
For all their faults dotnet and java make it really easy to not mangle up the stack trace.
[0] https://www.microsoft.com/download/details.aspx?id=100432
I draw the line at nice urls though, I think that's valuable to the client app and the user. At the very least, bookmarks work. Even with all the other state than can exist, it's a solid and useful reference point.
https://stackoverflow.com/questions/45016234/what-is-idempot...
https://en.wikipedia.org/wiki/HTTP#Request_methods
I can't say I agree. That would be a good idea in a world where users never encountered errors in normal circumstances, but in fact computers don't work very well and users encounter errors on a regular basis. Using computers is a skill. It takes study. You can either pretend that it doesn't, giving users something underpowered that is going to break anyway, or acknowledge that computers are complicated, and build tools and resources to help users navigate them. And users should recognize it as folly to try to use the most complicated tools on the planet today without any understanding of how they work.
This doesn't really apply to HTTP status codes. They're largely useless. It does apply to the way my Macintosh told me of a misconfiguration after I reinstalled the operating system. Somehow the people at Apple thought an error code and a brief description would be scary, so they opted for this absolutely terrifying icon instead:
https://i.stack.imgur.com/Y1teY.jpg
(Not my picture, by the way.)
This is why interfaces made by programmers tend to be impossible to use. Our minds simply work differently than normal people. In the 99% case, that icon will tell a user precisely the same information as any kind of detailed error log, which is "Oh no, something is broken, I should go to the Apple store."
Cars show error codes every few months or years and there's nothing the average driver can do to fix them. Computers show errors on a daily basis and most of them are trivially fixable.
> Computers show errors on a daily basis and most of them are trivially fixable
As they say, "citation required". How do I fix my Windows Update 0x80070422 error? (And yeah, I know, don't use Windows -- but I have plenty of *ix examples as well...)
(Not just snarky - this does fix a large percentage of errors regular users encounter)
But then, I'm a dev, not a normal person.
The annoying part for folks used to having control (eg power users) is that someone else decided that that was enough info for drivers. If you want the power-user car UI, you'll need to get out of the driver's seat and put on your mechanic hat. (Like sibling comment who purchased an ODBC reader.)
That's not enough information. At a minimum, there should be a way to distinguish between "you should make an appointment with a mechanic at your earliest convenience" and "pull over right now and call a tow truck, or you'll have to completely replace your engine and transmission".
No, it doesn't. The light comes on for routine maintenance that doesn't require a shop, and it comes on for things that might require a shop, but not urgently as well as things that are urgent.
I did get an ODBC reader just for this reason. But I shouldn't have had to. The car should just give me the code(s) itself.
> The annoying part for folks used to having control (eg power users) is that someone else decided that that was enough info for drivers.
I'm not annoyed at not having control. I'm annoyed that whoever decided that a single light gave enough information was incorrect.
Transparent error messages are more useful, and gatekeeping drivers with a connector and a list of codes should be considered unethical. Too many industries are trying to sell you something, but not let you make it yours or let you understand it. Before long, the value proposition will fall.
This is why I bought one of those OBD reader things so I can have more of an idea of what is actually going on. Not that I really understand anything that it says, I’m pretty clueless when it comes to car stuff, but it sure makes me feel better
The only time I ever got a check engine warning, the problem was obvious from the physical symptoms: cylinder misfiring. Well, I didn’t know what that was when it started happening, but now I do. Drove it to the mechanic and they replaced the spark plugs
Users' critical thinking skills can be fine, but sometimes they choose not to apply them for things they don't want to think about. That's totally normal if computers are outside their purview or they just want technology to work.
No small amount of people just take their car to the shop and don't try to interpret the errors. Knowing when to make your users think comes with the product territory and knowing your audience, and also considering "how important is surfacing that error detail, really?"
If you want the dirty secret for why, it's because we can be lazy about things we don't care about and/or critically thinking about everything is exhausting and sometimes you have more important things to do. They just want it fixed.
So a car may have different lights/states from "low fuel", "tire pressure", "door ajar" - to "service soon" to "failure imminent". These are all meant as calls to action by a typical driver, including potentially having them escalate to a mechanic/service center.
It is the mechanic can read off the status codes of the car computer to help further diagnose the issue.
A 401 in a browser indicates how the _browser_ can react to insufficient authentication, via the instructions in WWW-Authenticate headers.
The majority of status codes provide very little instruction to the browser, and provide even less to the end user. "400 Bad request" doesn't include instructions on how the browser can fix the query or form data being submitted, nor is there a process to inform the originator that they are linking to a location incorrectly. To the end user, a 400 error is even more worthless - there is nothing about a 400 that gives instructions on how to get the problem repaired.
The trend for development is to define errors which describe each failure case and to delegate those errors up. A robust system however needs to think about failure cases holistically and along with their recovery steps. Once you do this you typically have significantly fewer errors, because you have identified the appropriate recovery steps.
I think what's been lost -- or perhaps never been gained -- is an art of dual tiering error condition messaging.
Highest visibility messaging should be the simple & for the most general audience: "You Gave us Bad Information, here's how to fix it" for cases where that applies, with more information available for training users if they want it.
When it's an application or systems failure: "Something went wrong on our end, not your fault" should be the high visibility message. Then maybe "here's a request ID, you can contact this support channel about it if the problem persists". Then somewhere low visibility "here's some detail about what's going on under the hood if you want to look."
This is part of a general sin in product / UX as far as I can tell: the "don't make me think" mantra became something itself people stopped thinking about and transformed effectively into "don't LET me think."
Edit: Is the blue screen of death still a thing these days? I haven't actually used Windows in a decade.
That error is the boot firmware telling you it can’t find a bootable OS. It doesn’t know what language you speak, and would an error code really be helpful? If you’re knowledgeable enough to know what the error codes mean, you would know that cmd-V gives you verbose logging.
This is exactly the sort of thing I'm talking about. You assume that anyone who doesn't know every hidden Macintosh hotkey is so ignorant of computers they won't even know how to look up an error code. If there are magic hotkeys that modify the boot sequence, that might be some information I would like to know when trying to boot my computer! Why not display those hotkeys during the boot sequence like a normal OS?
This is an opinion that, on a personal preference level, I share. It's not, however, a universal truth. An optimally useful computer should be a human interface to information or control of something. The best computer is one that interprets a messy human command, produces the information or action that the human actually wanted, and requires no training at all to use.
Such a machine would be anathema to me, personally, but it would be objectively the best possible general purpose computing device.
Then again, I also think people should be taught better than to hop on the Web without any training or knowledge. Computers and illiteracy go together about as well as books go with illiteracy. It takes effort to be computer literate, and hiding the information will make that journey to literacy more daunting than it needs to be.
* Which for me has almost always just meant some oil change "timer" was up, not even that any meter detected my oil was wearing out.
1. the attacker can see (but not decrypt) the victim's TLS traffic to example.com
2. an attacker-controlled website makes the victim send many different invalid requests to example.com, each of which gets an error message
3. some data in each request is attacker-controlled, but authentication data in headers is filled in by the victim's browser
4. example.com compresses response data before encrypting it
5. because repetitions affect compression, the response size is smallest when the authentication data matches part of the attacker-controlled data
6. after enough requests, the attacker knows the authentication data to login to example.com as the victim
One workaround for CVE-2012-4929 was to set up the server so that an error message never depended on the request data. Before CVE-2012-4929 was announced, people thought it was sufficient to sanitize the error message (i.e., avoid XSS) but CVE-2012-4929 prompted a shift toward producing exactly the same error message for all invalid requests. (Not sure, but I think this was the original motivation for Google's famous "That's an error. That's all we know." messages.)
There were better CVE-2012-4929 defenses later, but the cargo cult had already formed. (Some subset of) a generation of developers believed that customized error messages were Very Bad because they enabled account takeover.
500 / 503 seems to fit any and every error these days, or the classic 200 OK for a page not found.
A malicious server can just as easily send the wrong status code, as well as listing the wrong status code in the accompanying html - so if the browser did show the real status code more prominently to the user, that wouldn't actually help in such a case, or would it?
The days of a bespectacled web user, thoughtfully musing over an error message, while fiddling with a self-propelling pencil, sat at a Sun/SGI/HP/IBM X11 session are long gone.
Web browsers handle the status code correctly by displaying the error in the response body. 500 isn't for end users - it is for web crawlers and caching proxies.
Or much more importantly, errors incorrectly returned with 200/OK success codes are cached, semi-permanently breaking your site.
If you've get helpdesk staff telling customers to "clear their browser cache", this is one common reason why this "works" as a fix.
Please, I beg you: stop being "nice". Stop catching exceptions and dropping them on the floor! Let them bubble up to the web framework pipeline so that an error code is sent.
Your CDN will thank you. Browser caches will thank you. Corporate proxy servers will thank you. Application monitoring tools will thank you. Load balancers will thank you.
I kid, I kid. None of those will send you thanks in an email. Instead, they'll work tirelessly in silence to deliver your application as intended, instead of holding on to transient errors for days on end and upsetting your users.
The exception needs to bubble up to the request pipeline, which will set an integer error code, and then... redirect to a generic "sorry we broke" error page.
Showing the full exception stack trace and other sensitive bits and pieces is for local debug mode, not for production.
Open Telemetry, Application Insights, New Relic, etc… will all stamp the request with a unique id and associate any errors with it.
Most developers I notice just catch the error right away and make the function return something non-sensible like a 0 for a string value function.
Slightly better developers just let the exceptions bubble.
The rare breed looks at what exceptions are being thrown, decides which ones to handle at which stack level, and repackages them as needed when the error cannot be handled that deep in that stack due to a lack of context. Then they write framework-level exception handlers for errors that rise to the top because they cannot be corrected at a higher stack level to give users specific error messages with user-correctable actions without revealing anything sensitive. “Your image is too small, wanker.”
On Error Resume Next
In the first line of every function. It's tells the Interpreter:
"Shhhh, it's fine. Just ignore errors. Division by zero? No worries. It's Fiiiiine. Try to access inexistent index of an array? Who cares, it's Friday!"
Boy the reports that my browser “wasn’t ready for prime-time” as a result…
It now only shows if the domain can’t be resolved, people are happy
Chrome outright refuses to show the HTML of a 500 response in favor of its own dinosaur animation or some garbage, or did that change?
That was a mistake.
Every once in a while they remove widely used functionality from the UI or bury it behind a lot of other crap, so someone has to invent an extension to bring it back. It's terrible.
All the alternatives have varying degrees of suckitude, and there's no way to just make an alternative browser without like $1.5 million dollars and two years of development.