Avoid fancy coding. The more complicated the code, the more likely there's bugs. Usually on modern systems, clearly written code will be fast and small enough.
Use available libraries. The easiest way to not have bugs writing a utility routine is to not write it.
Learn a few formal techniques for the more complicated stuff. If there's complicated conditions, nail them down with pen and paper. Ideally, know some proof techniques. If I can prove code correct, it's almost always good except for big, dumb, obvious bugs that are easy to fix. Obviously, this only goes so far, but sometimes you can formally reason about small but complicated things.
For existing code, learn how to refactor: how to make small changes in the code, often using an automated tool, that make the code more readable without changing the behavior.
Don't do anything too quickly. Taking a little time up front to do things right, to check what you've done, and to think about what you're doing can pay off big time later.
Once you've written the code, use what you've got to make it good. Unit tests are great. You can often write tests ahead of time, which can be great feedback (if done consistently, this is test-driven development). Compile with warning options, and pay attention to the warnings.
Get somebody else to look at the code. Formal code reviews are good, but they may not be at a convenient time. Pull requests, or similar if your scm doesn't support them allow for asynchronous reviews. Buddy checking can be a less formal review. Pair programming ensures two pairs of eyes look at everything.
"production-quality code" is whatever another user, who is not you, is...
- able to use with no or minimal support. If every action is met with a bug, your software will go into the garbage
- able to understand how to use with minimal support or documentation. If your user can't understand how to use your software, it will go into the garbage.
- willing to use because it adds value. If your software adds enough value, maybe they'll even give you money for it. If it doesn't add enough value for you to give it away for free, your software will go into the garbage.
THAT IS IT.
Some people need absolute fault tolerance. Others don't mind as much if some data gets lost when there is a crash... assuming they see crashes very infrequently. There are no hard set qualities or requirements. And no customer cares about test coverage, what they care about is the three above points. Test coverage is a tool (one of many) you can use in order to get there, but plenty of software, some of it even good, has been built with nothing but manual testing.
Whatever software you build, the requirements are between you and your customer and if you are building software for general consumption, then pick one or few target groups and don't try to be everything to everybody. Trying to come up with some kind of generic mold seems to me rather silly.
Instead, of trying to predict or guess when your software will be production-ready, why don't you work with your customer? Give them a preview but explain that it is not production ready. Publish it on your own server and ask them to use it, poke around and give you feedback. Continue working with them until they are happy with what you gave them. In other words, they will tell you when it is production ready.
Best Answer
Grab as much information about the problem as you can (logfiles etc.) and then rollback the production servers to a working state. That's a pain from the developer's point of view of course, but is most likely a given.
Next, try and see if you can reproduce the problem in a development environment. If you can, then fix it and try releasing again.
If you can't reproduce it, then see if you can add more diagnostics and release to one server for a short time to get more information about the problem.
If that's not possible then look more closely at the differences between production and the dev/qa environments and try to make a dev environment closer to production.