When troubleshooting code I try to follow a set path in order to quickly isolate the issue. The problem is that I’m just as guilty as others at trying to shortcut the process. One major trap I fall into is the time consuming ‘wandering’ into certain parts of the code and encountering a road block by not staying on the original path. In doing this I often end up chasing problems that are caused by other problems that need to be addressed first. With that being said I have developed a good instinct for finding problem code.
What I want to do is share some insights I have discovered in trying to track down code issues. I will try and make this as generic as possible. The fact is most languages have error detection code and specific programs designed to help with coding issues for the particular language you may be using. In the final analysis a large number of these return errors that are not even remotely connected to the real issue. If you have used these tools you know what I‘m talking about. Often they can point you in a general direction, sometimes the specific line of code, and other times send you off looking in an area that just consumes time and confuses you. General troubleshooting is basically the same in all languages and following certain rules can save you time and lessen frustration.
These are the first steps:
1. Uninstall then Reinstall the program (re-download or re-upload if that is how the program was delivered, if compiled re-compile) this includes removing any temp files, directories, or anything else connected to the program.
2. Check version compatibility of connected programs, libraries, or any other helper files, and check path settings.
If you are getting an error
There are two types of coding errors, those that actually present an error message and those that break the program without an error message. There is actually a third, where there is no error message and the program works but somewhere in the code is a time bomb that eventually will cause the program to degrade to one of the first two errors or to not work properly. There is also the situation of where the program works but if you test it with a testing program or some type of code compliance test it fails. My philosophy has always been that if the program works as designed after testing it on a variety of operating systems and browser flavors you’re good to go. If a problem exposes itself later you can always revisit; but hey if it works as coded then your goal is reached. –Opinions and goals may vary- I always scratch my head when I hear about fast code; fast on what computer and compared to what?
Don’t misunderstand, if you can optimize by all means do it. Keep in mind though that the machine will only execute so many instructions per second so the goal should be to write your code so the machine has less to do, not more. I admit I don’t write ‘pretty’ code. What I can do is write code that works and dig into code to find problem areas. I have learned to create landmarks in my code so I can back track to certain execution points. So let’s talk about getting errors.
First off, if you are getting an error you are one step closer to finding the problem. One of the first things I like to do if I encounter a code issue is to get it to error; but we’ll discuss that later. If you’re getting an error the first rule is don’t trust the error message to be correct. Many times it will be not be correct so just assume that the error is a starting point to back down in your code flow.
By backing down I mean start at where it is breaking and follow your code flow backwards to the previous branch in your code. What part of the code is calling the part that is breaking? If the error is specific and points to specific line of code like missing a closing bracket, missing a library, can’t find something or something missing, path is incorrect, or some other specific message, then fix the specific problem first. If it is generic and doesn’t point to a specific line code then put a break in at the calling function or line of code that is calling the problem code or just prior to the problem code.
It's time for another break
I try and put breaks in about every section of code that performs a separate function or duty. By turning these breaks on at different points you can usually isolate the problem code. It is possible to find a code error and later realize that the problem was actually started way up the line of code. That is why it is important to put in a lot of code breaks. If you start the code to run to a certain break you can then check the variables and other parts of the code to that point to see if is working as expected. The mission at this time is to isolate the problem. The only way to accomplish this is to break apart the code and look at each section separately. By taking out all the variables, one at a time, you can pinpoint at what place the issue is actually being created. The variables I’m speaking about are all the components of the program and the environment that the program is running in. It often helps me to footnote code so I know what that section of code is doing. This is especially helpful in nested loops.
I’m trying to keep this generic so I will not use any specific example. You can isolate the problem by listing all the variables that can affect the program as potential culprits and eliminating these. Included in this list are the particular language, components or libraries, versions, transports, server OS, server components, client OS, client components, and a long list of other potential variables. One plus in this is that most of time the error will be generated from a part of code that eliminates a lot of these variables for you and in some cases not. Depending on the language there might be inherit code alerts and built in error handling that will either help or hinder your troubleshooting process. There may also be coding tricks that can turn error reporting on or off but this is also a slippery slope in troubleshooting.
Regardless of any programming error routines the language has, there is no substitute for eliminating all the variables that could be causing the error. If you’re lucky the error message will point you to the exact point of code you need to look at. If not then your only choice is to start the program with a break at the first branch and then check the program for proper execution to that point. Then continue with breaks until you finally see the program return an improper response. If you’re working with a compiled language you can benefit from the fact that most compilers will not compile miss-structured code and will return where in the code it’s breaking. You still have to follow the same process to locate an evasive code issue.
To this point we have spoken about creating code breaks at certain execution or function points; you may also have to isolate certain logics in the code. If the error is being created in the way a loop is being performed or an array is being built, or any other logic step in your code, you may have to back track logic flow in your code. The same process applies for this. What is the logic? What is creating the logic? Where does it start? What is interacting with the logic? Start by going to the logic creation and create breaks as the logic flows throughout the code. If the logic is used by other code logic then isolate the original logic and follow the flow to that point and check that the logic is performing properly. If other parts of code are using the logic make sure it’s not being altered or changed as it flows by putting in code breaks at the points that the logic is being used.
To recap so far; when troubleshooting code issues start at the beginning and follow the code flow by putting in breaks or stops and check the program execution to that point. You can also break the code out separately from the main body of code and see it behaves outside the rest of the code. Start removing anything that could be causing the error. If you have removed all the variables that could be affecting the program, and still allow the program to execute, then change those variables in some way; different browser, different OS, different server, different version, different library, etc. If the program will not execute than take out all the code except your first function. Don’t totally rely on the error message to be accurate. Instead use it as a hint to what the problem might be.
No error message
Now what about a code issue that does not present an error message? Your first priority here is to get the program to error. Some languages will suppress error messages so try turning this off or adding code that will produce an error message. Depending on the language there are tools that allow looking into code flow that monitors variables, output, calls, and code events. Look at the issue and see in what part of the code this function or task is being performed. Once you have located the code examine it for proper coding and put in breaks to follow the task flow so you can observe at what point the issue is being created.
You may not be able to produce an error but you can find where in the code the task is being handled. Once you have found that code you can start using the same process as we have discussed with having an error message. Most of the time these types of errors are externally created by some outside influence so removing the variables or changing the variables will give you success. Another common problem with this type of code issue is code logic. Just follow the path of troubleshooting logic issues to find the problem area.
It is also possible that you’re not getting an error message - the program is working - but it’s not working as programmed. The same process applies to locate the point in code where this is happening. If not being influenced by an external variable this will probably be a logic issue but it could also be a masked error that is not being reported. As I said before you should try to get an error by using code or available tools but in lieu of an error you have to go to the section of code that is controlling the unexpected behavior. One last point is sometimes you have to track the code flow across several modules or program files so creating a code map can be helpful. A code map is a file that shows how separate program files connect and what functions are used or shared by these files.
Troubleshooting code can be very frustrating but if you stay the course and follow a set path you can cut down on the time and frustration of finding that elusive code problem.
by Jim Atkins "thedosmann"