Most developers might already know how to get basic error information from the ActivePDF family of products. However, have you ever wondered how to get detailed information about an error? You probably have some basic error handling in place for your application. It may look something like this:


' OpenInputFile
varReturn = tk.OpenOutputFile(varPath & "input\" & varFileName)
If varReturn <> 0 Then 
   log("'" & Method & "' failed with a '" & varReturn)
End If

 


What’s interesting is that there are options in ActivePDF products that allow you to get significantly more information about an error. For example, Toolkit has several methods which can return additional information about a problem…


' OpenInputFile
varReturn = TK.OpenInputFile(varPath & "input\" & varFileName)
If varReturn <> 0 Then 
Error("OpenInputFile")
log("EncryptionError: " & TK.EncryptionError)
log("ExtendedErrorCode: " & TK.ExtendedErrorCode)
log("ExtendedErrorDescription: " & TK.ExtendedErrorDescription)
log("ExtendedErrorLocation: " & TK.ExtendedErrorLocation)
End If

 


In this example, the original method would simply return an integer value of “0” for a success, or a “-1” for a failure to open the input file, but it wouldn’t provide you any details about why Toolkit was unable to open the input file. If you use the additional properties on a PDF file that is password protected for example, you would see the following information…


OpenInputFile(Input.pdf) = -1
EncryptionError: 0
ExtendedErrorCode: 0
ExtendedErrorDescription: Owner password (獤ﻟ翼) is not valid
ExtendedErrorLocation: PDFile::Open

 


Here you can see that the file is password protected, and the correct password information was not provided for Toolkit to use.


* Beginning with Toolkit 8.1.4, Toolkit OpenInputFile method now returns error code -2 for an invalid user password, and error code -3 for an invalid owner password. 


In some of our other products such as DocConverter and WebGrabber, we return a full error object instead of a simple integer value. You can set up similar basic error handling which just tells you if the conversion was a success or not, similar to what Toolkit has always provided. With the error object, you can now get significantly more information about what’s going on than a simple success or failure. Below is an example of what might be used to capture all the error data when you run into a problem…


DocConverter:


public static void ErrorHandler(string strMethod, DCDK.Results.DocConverterResult actual)
        {
            StreamWriter log = null;

            // Check to see if logfile exists for this thread, if not create one, if it does append to it.
            if (!File.Exists(Application.StartupPath + "\\ErrorLog.txt"))
            {
              log = new StreamWriter(Application.StartupPath + "\\ErrorLog.txt");
            }
            else
            {
              log = File.AppendText(Application.StartupPath + "\\ErrorLog.txt");
            }

            // Write error message to LogFile
            log.WriteLine(DateTime.Now);
            log.WriteLine("Method: " + strMethod);
            log.WriteLine("Status:" + actual.DocConverterStatus);
            if (actual != null)
            {
              log.WriteLine("Error Status: " + actual.DocConverterStatus.ToString());
                log.WriteLine("Error Details: " + actual.Details);
              log.WriteLine("Error Origin.Class: " + actual.Origin.Class);
                log.WriteLine("Error Origin.Function: " + actual.Origin.Function);
                if (actual.ResultException != null)
              {
                    log.WriteLine("Error Exception.Message: " + actual.ResultException.Message);
                    log.WriteLine("Error Exception.StackTrace: " + actual.ResultException.StackTrace);
                    log.WriteLine();

                  var inExc = actual.ResultException.InnerException;
                  while (inExc != null)
                    {
                        log.WriteLine("Error " + inExc + ".Message: " + inExc.Message);
                      log.WriteLine("Error " + inExc + ".StackTrace: " + inExc.StackTrace);
                        log.WriteLine();
                        inExc = inExc.InnerException;
                    }
                }
            }
            log.WriteLine();
            log.WriteLine();
            log.Close();
        }

 


You can still see a simple status of the conversion by using the "actual.DocConverterStatus" to quickly see if the conversion was a success or a failure. Now, with the full error object, we see the specific error details, the class and function where the error originated, a detailed exception message, and even loop through the stack trace.


In this example if we sent in a password protected Word document, the DocConverterStatus would simply tell us that the conversion failed with "OpenInputFileFailed". However, if we use the extended error handling as described above, we would see the following information...



Using this additional information, we can very quickly and easily see that the file in question was password protected, which prevented us from being able to open the file. To resolve this, we simply need to remove the password protection from the file, or provide the password information to DocConverter so it is able to access the file and process it normally.