It’s late in the day and you’re running on fumes. You decide to run your code through one last unittest before calling it quits for the day.
And then it happens. Ba-boom! It all blows up. Unhandled exception. Error code 74708. No error message recorded. Where do you start looking for the cause?
One thing that can help is to be able to find out what that particular error code means, so knowing a bit about how they’re defined, and where, can be helpful.
All the error codes that Teamcenter uses are #defined within the header files. Generally speaking each module has it’s own range of error codes which usually allows for at least 100 distinct error codes although it can allow for several thousand. Typically only a small subset of that range is actually assigned a value. The remaining space is reserved for future expansion.
The base value for each range of error codes will be #defined something like this:
#define MODULE_error_base <em>nnn</em>000
Where nnn are some numeric digits. The actual size of the error_base number will vary from module to module, but it’ll always end in at least a couple of zeros. The error_bases are all defined in a couple of header files: error_bases.h and emh_const.h mainly. There may others, but honestly, memorizing which headers define the error_bases isn’t all that important, as you’ll see later.
There will also be another header file that defines the actual error codes for the module. Within that header file the error code definition will follow this pattern:
#define MODULE_first_error (MODULE_error_base + 1) #define MODULE_second_error (MODULE_error_base + 2) #define MODULE_third_error (MODULE_error_base + 3) // etcetera...
So now, knowing this you can track down what the error code means.
1. Figure out the base number for this error code
In our example the error code is 74708. It’s probably a pretty safe bet to assume that the error_base for this code is 74700. Our second guess would be 74000, but it would be very unusual for a module to #define over 700 different error codes.
2. Find the name of the error base.
Now you could open up each the header files that #defines error bases and look for the value 74700, but I find it easier to just do a full search of the include directory for any header that contains that value. When we do that we discover that in the header file emh_const.h, there’s this entry:
/** CE ERRORs */ #define EMH_CE_error_base 74700
So the error_base we’re concerned with is called EMH_CE_error_base.
3. Find the header file that #defines the specific errors codes for that error_base
In other words, search the header files for the term EMH_CE_error_base and see what turns up. When we do that we discover that EMH_CE_error_base shows up in the header file ce_errors.h
4. Find the definition for this specific error code
Within ce_errors.h we find the following lines:
#define CE_ERROR_BASE EMH_CE_error_base #define CE_init_error ( CE_ERROR_BASE + 1 ) #define CE_no_load_usersession_object ( CE_ERROR_BASE + 2 ) #define CE_no_type ( CE_ERROR_BASE + 3 ) #define CE_no_properties ( CE_ERROR_BASE + 4 ) #define CE_invalid_data_type ( CE_ERROR_BASE + 5 ) #define CE_data_type_not_supported ( CE_ERROR_BASE + 6 ) #define CE_argument_number_out_of_range ( CE_ERROR_BASE + 7 ) #define CE_invalid_argument_type ( CE_ERROR_BASE + 8 ) #define CE_invalid_global_operation ( CE_ERROR_BASE + 9 )
So you see that here that got a little bit tricky, but not too tricky. First they re-#defined EMH_CE_error_base as CE_ERROR_BASE. Then they went along with the usual pattern for #defining error codes. We’re looking for 74708, or in other words CE_ERROR_BASE + 8. And there it is, CE_invalid_argument_type. Now I have a clue why my code crashed. Somewhere I’m calling a CE_ function (CE is the Condition Engine module, by the way) and I’m passing the condition an invalid argument. So, my next task is to look for which conditions I’m calling with a CE function and double checking what data types the Condition is expecting versus what data type I’m actually passing.
In this specific example it turned out that I was invoking a Condition that expected an argument of type Item, but I was passing it the tag_t of a ItemRevision instead. Once I passed the Condition an Item instead the bug was fixed.
Have you ever been stumped by a mysterious ITK error code with no associated error message?