Web developers, at least good ones, try not to release the programs they write without having full confidence they’ll work under normal (and many abnormal) circumstances. Testing is an absolutely necessary part of every development cycle.
Despite a dizzying variety of browsers out “in the wild,” we can’t afford to release something which will fail in more than a tiny percentage of cases. Websites like caniuse.com exist just so developers can run the percentages and decide what features they can comfortably add to their sites. Libraries of shims like webshims exist to help developers cover the gaps. When a program goes live, it should already be well-tested, hardened by fire, ready to serve now and into the future.
Unfortunately, no matter how much effort goes into failure-proofing a program, anything can break under the right conditions. Here are a few of the causes we’ve run into over the years, plus what can be done to minimize their threats.
1. Reliance on outside services
Nearly every technologically-inclined company with a large web presence provides useful services which they will allow smaller developers to hook into through the use of application programming interfaces, or APIs. For instance, both Microsoft Office 365 and Google Drive provide feature-rich, easy-to-use, secure web applications which allow users to create public calendars. A developer can then (with the user’s permission) hook their own program into the Google or Microsoft API engine and extract data to display on their corporate site. The user never has to touch the site, and the developer doesn’t have to create an enormous complicated interface for the user.
Many times, this is a win-win scenario. However, APIs are not eternal. Companies will change them over time to be more secure or better align with their services. They can quietly move a connection into “deprecated” or “discontinued” status. As far as the consumer of the API is concerned, everything continues working without a hitch until it suddenly stops. Once the API goes away, a formerly robust application will almost certainly stop working.
The only way to prevent this kind of breakage is for the developer to remain in the corporate pipeline and stay informed about upcoming changes in their most current API version. Most companies will announce changes several months in advance unless an emergency (finding a security vulnerability, for instance) requires a rapid update. As long as the developer is subscribed to their newsfeeds and remains up to date with industry news, they won’t be blindsided. Vigilance is the developer’s best option.
2. Service interruptions
The user’s connection to the server is another possible point of failure. The developer has no control over whether the user’s computer drops off the internet. If the disconnect happens in the middle of a crucial data transfer, the program could possibly wait forever for the end of a data string that never comes. Add up enough of these drops over time and eventually the program will have more and more hanging connections. Since each connection consumes a small amount of server resources, a crash is inevitable at this point.
The solution to this is so simple that programmers sometimes forget to do it: timeouts. A timeout is a small subroutine which monitors data transfer at periodic intervals. If no data has come across from the end user between one interval and the next, the program cancels the transfer.
3. Malicious user input
Programs on the Web can fall victim to all types of ill-mannered users. From an angry customer mashing keys over and over again on a contact form to sophisticated programs designed to exploit known server or programming language vulnerabilities, it’s a dangerous Internet out there.
Developers have to be very careful dealing with data from a source they don’t control completely. A typical practice is input sanitization. Every piece of data from a Web-based form is checked for length, the presence of special characters, and internal codes which could potentially cause unwanted behavior, before being passed on to the rest of the program. Depending on the level of thoroughness and the requirements of the website, some developers will go so far as to sanitize information coming from all external sources, including APIs. Usually, though, sanitizing form input is more than enough protection for a site.
4. Bad data
Most programs are created to display dynamic data from a number of sources, including human input. And through no fault of their own, humans hit the wrong key sometimes, sending bad data right into a program. The old programming adage of “Garbage In, Garbage Out” applies here, often causing inappropriate output at the best of times and crashing the program completely at worst.
Programmers often feel they can be more lax about the integrity of data provided from sources inside the company. Mistakes aren’t necessarily malicious, and everyone makes them. Applying input sanitization to every possible piece of data from every possible vector is prohibitively expensive in both computing cycles and development time. Consequently most developers employ judicious amounts of error trapping to minimize the impact of bad data.
All programming languages have built-in hooks designed to catch errors as they happen. These hooks allow the programmer to direct the program to perform alternate tasks depending on the type and severity of error. At the first sign of unexpected input, a well-trapped program can exit gracefully with an “Oops, something happened” message or display data from backup sources or recent data caches.
On the other hand, trapping every single bad outcome is a needless expense for relatively little benefit; if we never encounter an error which was extremely unlikely in the first place, then any time spent trapping that error was wasted. Once again, programming becomes a game of probabilities. Experienced developers know the most likely points of failure and set their traps against them. If the one-in-a-billion error does happen, a quick fix afterward is the most prudent solution.
5. Server errors
No matter how bulletproof a program may be, it’s only as good as the server it runs on. Web servers are applications which has been tested and re-tested for years on end, and so have become extremely robust. They’re also very complex, and any system with a lot of “moving parts” (read: programs running in parallel) can fail at unexpected times. Sometimes, all it takes is one piece of data out of place to bring the whole structure to a halt.
Unfortunately, there’s not much a developer can do about the odd server error, any more than a mechanic can prevent a driver from running over a rock which gets jammed up in the engine. In this case, only the most basic IT rule applies: try turning it off and on again.
And beyond …
The end of a web development cycle is never really the end. Time has a tendency to show the cracks in any program. Even a bulletproof program can become obsolete as technology and the marketplace both evolve. It’s always good practice for any company with a Web presence to set aside a maintenance budget to make sure everything stays up-to-date as time goes on. A few hours of work every few months will help ensure that your site will stay relevant, useful and error-free for many years to come.