Understanding the Connection Between Application Output and ErrorLevel

Many readers have a disconnect between application output and the ErrorLevel variable found in batch files. I’ve received more than a few e-mails where readers don’t quite understand the whole concept behind the ErrorLevel variable. They think it actually signifies some sort of mystical operating system derived error, when it isn’t anything of the sort.

A large part of the problem is that those readers who commonly work with batch files aren’t developers and many developers don’t work with batch files. In fact, even though many administrators are moving back to command line utilities because working with the GUI is time consuming and inefficient, many developers have decided to eschew the console application in favor of GUIs with fancier user interfaces.

Another problem is that ErrorLevel is inappropriately named. It should really be named ApplicationOutput. I’m sure that at one time the intention truly was to convey some sort of error information, but even Microsoft uses ErrorLevel for other purposes.

Let’s take a practical look at the whole concept of ErrorLevel beginning with a simple C# application to generate the codes. When working with C#, you’ll find that the output is now called an ExitCode as shown here.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace GenerateOutput
    class ExitCode
        static void Main(string[] args)
            // Create a variable to hold the exit
            // value.
            Int32 Value;
            // Make sure there is a variable provided as input.
            if (args.Count() > 0)
                // Determine whether the input is actually a number.
                if (Int32.TryParse(args[0], out Value))
                    // If it is, then exit using that number.
                    // Otherwise, exit with an error value of -2.
                // Exit with an error value of -1

The only purpose of this application is to generate exit codes given certain circumstances. The first check determines whether the user has supplied any sort of input at all. If not, if the user simply types GenerateOutput without any arguments at all, then the application exits with a value of -1 to indicate an error. Likewise, if the user types something other than a number, such as GenerateOutput Hello, the application exits with a value of -2 to indicate a different sort of error. Only when the user supplies a number does the application exit with a numeric value.

The batch file used to test this application is equally simple. All it does is call GenerateOutput with the value (if any) that the user provides to the batch file, TestOutput.bat. Here’s the batch file code.

@Echo Off
REM Run the application.
GenerateOutput %1
REM Most application output are status indicators.
REM You can perform specific actions for a specific status.
REM Applications can also provide a success indicator.
REM Errors are normally negative numbers, but can be anything.
ECHO The value you provided is higher than 1.
ECHO You provided an input of precisely 1.
ECHO An output value of 0 indicates success!
REM Here is the beginning of the various messages.
ECHO You must supply a number as an argument!
ECHO You must supply a number and not text or special characters!
REM Here is the ending point.

As you can see, the tests check for errors, success messages, and non-error application output. Any combination of console application and batch file can do the same thing provided the developer and administrator get together to work out the details or the developer at least documents the exit codes.

The process is the same each time. Test for an ErrorLevel value, then go to the label specified, execute the directions, and then go to the end of the batch file. The ErrorLevel values must appear in order from greatest to least in order to work correctly. Here is some test output from this test application and batch file pair.


The point of this exercise is to ensure that developer and administrator alike realize the importance of the exit code (ErrorLevel). The application should use it to provide some sort of status information that the administrator can then use to track how well the application works in an automated setting. Let me know if you have any questions at John@JohnMuellerBooks.com.


Using CodeBlocks 10.05 – Part 4

The testing of my book,  C++ All-In-One Desk Reference For Dummies, for use with CodeBlocks 10.05 continues. I introduced this new version in Using CodeBlocks 10.05 – Part 1, where I discussed the general look of the new version.This post concerns Book IV Chapter 2 (found in \Author\BookIV\Chapter02).

On page 431 you see the explanation of the LValueAndRValue example. This example is supposed to fail in a specific way and it still does just as the book specifies, but with a different error message. I’ve pointed out a few other error message changes in other posts (you can see the entire list of posts for this book in the Category Archive for C++ All-in-One for Dummies). In this case, the error message has changed to:


error: lvalue required as left operand of assignment

The change isn’t a big one, but some readers could find it confusing. A few readers have asked how you’d fix the example. Well, you’d make DontKnow() to look like ChangeMe() as shown here:

int &DontKnow()
    return uggle;

The StaticCast example shown on page 437 is designed to show a warning message in its final form. This warning message is the same in CodeBlocks 10.05:


warning: unused variable ‘f’

Some readers are confused about how to get the error message described in the book. It may have been best in this case to provide two examples on the disk. However, you can easily change this example to fail as described on page 437. Simply change line 6 of the code to look like this:

class AnotherType {}; //: public FinalType {};

However, when you try to compile the example, you’ll find that CodeBlocks 10.05 again changes the message slightly. In this case, you’ll see:


error: invalid static_cast from type ‘AnotherType*’ to type ‘FinalType*’

The differences are small in this chapter, but worth noting. CodeBlocks 10.05 attempts to make the error messages easier to read. If you see small differences in the error messages and you’re using CodeBlocks 10.05, there is probably nothing to worry about. Please do contact me if you have major concerns about a CodeBlocks 10.05 different at John@JohnMuellerBooks.com.


Creating Sensible Error Trapping

Errors in software happen. A file is missing on the hard drive or the user presses an unexpected key combination. There are errors of all shapes and sizes; expected and unexpected. The sources of errors are almost limitless. Some developers look at this vastness, become overwhelmed, and handle all errors the same wayby generating an ambiguous exception for absolutely every error that doesn’t help anyone solve anything. This is the worst case scenario that’s all too common in software today. I’ve talked with any number of people who have had to employ extreme effort just to figure the source of the exception out; many people simply give up and hope that someone has already discovered the source of the error.

At one time, error handling functionality in application development languages was so poor that it was possible to give the developer the benefit of a doubt. However, with the development tools that developers have at their disposal today, there is never a reason to provide an ambiguous “one size fits all” exception. For one thing, developers should make a distinction between the expected and the unexpected. Any expected errora missing file for example—should be handled directly and specifically. If the application absolutely must have the file and can’t recreate it, then it should display a message saying which file is missing, where it is missing from, and possibly how to obtain another copy.

Even more than simply shoving the burden onto the user, however, modern applications have significantly more resources available for handling the error automatically. For example, it’s quite possible to use an Internet connection to access the vendor’s Web site and automatically download a missing application file. Except to tell the user what’s happening when the repair will take a few minutes, the application shouldn’t even bother the user with this particular kind of errorthe repair should be automatic.

My book, C# Design and Development,” discusses a number of expected error scenarios that the developer can easily handle. For example, a user could press the wrong key combination. Instead of simply beeping it’s discontent, the application should tell the user that the key combination won’t do anything and provide a list of acceptable key combinations. The use of friendly controls can also help. Don’t use a textbox when a drop down listbox will work better. In fact, the textbox is the worst possible control to use in many circumstancesit should be the option of last choice. Chapters 4 through 7 of my book discusses a wealth of design issues, including the selection of a proper interface type (such as a dialog box versus an SDI or MDI form). It divides these decisions into those that affect application speed, reliability, and security, which is the smart approach to use in developing any application.

Exceptional conditions do occur. However, even in these situations the developer must avoid the generic exception at all costs. If an application experiences an unexpected error and there isn’t any way to recover from it automatically, the user requires as much information as possible about the error in order to fix it. This means that the application should diagnose the problem as much as possible. Don’t tell the user that the application simply has to endthere is never a good reason to include this sort of message. Instead, tell the user that the application can’t locate a required resource and specify the resource in as much detail as possible. If possible, let the user fix the resource access problem and then retry access before you simply let the application die an ignoble death. Remember this! Any exception that your application displays means that you’ve failed as a developer to locate and repair the errors, so exceptions should be reserved for truly exceptional conditions.

Not everyone agrees with my approach to error trapping, but I have yet to hear a convincing argument to provide unreliable, non-specific error trapping in an application. Poor error trapping always translates into increased user dissatisfaction, increased support costs, and a reduction in profitability. Let me know your thoughts on the issue of creating a sensible error trapping strategy at John@JohnMuellerBooks.com.


Handling Source Code in Books

One of the biggest conundrums for the technical writer is how to handle source code in a book. The goal is to present an easily understood example to the readerone that demonstrates a principle in a clear and concise manner. In fact, complexity is a problem with many examplesthe author tries to stuff too much information into the example and ends up obfuscating the very principles that the reader is supposed to obtain. So, very often simplicity must win the day in creating application source code for a book, despite the desire of the author to present something more real world, something with additional glitz and polish.

Because the goal of an example is to teach, very often the examples you see in a book have more comments than those that you see in real life. An example in a book must include as much information as possible if the code is going to fulfill its purpose. Of course, book comments should illustrate all the best principles of creating comments in real code. In short, if real world code looked a bit more like book code, then its possible that developers would spend far less time trying to figure code out and more time making changes.

Some readers will take the author to task because the code may not always provide the error trapping that production code provides. In fact, as with many teaching environments, the safety features in code are often removed for the sake of clarity. This problem plagues other environments too. All of my woodworking magazines post a note near the beginning of the magazine telling the reader that the safety devices have been removed for the sake of clarity and that no one in their right mind would actually work with woodworking equipment without the safety devices. Likewise, the code you see in a book often lacks good error trapping, making the principle that the code demonstrates clearer, at the cost of fragility. You can usually cause book examples to break easily, but no one in their right mind would create production code like that.

The feature that I’ve constantly worked on with the code in my books is accessibility. In as much as possible, the code demonstrates how to make an application usable by those with special needs. Of course, as with the exception handling, it isn’t always possible to add all of the required accessibility features without making the code less clear. Still, I’m a strong advocate of making code completely accessible whenever possible.

Readers will likely question just how useful book code is if it leaves safety and accessibility features out. Remember that the goal is to teach. Let me know your thoughts about source code in books at John@JohnMuellerBooks.com.