Errors and exception handling in geoprocessing


About errors and exception handling in geoprocessing

The geoprocessor's Execute method throws an exception if a tool fails. It is imperative that you always surround your code with at least one try-catch block. This approach makes your application more robust and prevents it from abruptly closing. It is equally important to get the messages from the geoprocessor or the result object.
A typical call to the Execute method should always be within a try block as shown in the following code example:
[C#]
try
{
    gp.Execute("Project_management", parameters, null);
    // Get geoprocessing information or warning messages.
}

catch (Exception ex)
{
    // Get exception and geoprocessing error messages.
}
[VB.NET]
Try

gp.Execute("Project_management", parameters, Nothing)
' Get geoprocessing information or warning messages.

Catch ex As Exception

' Get exception and geoprocessing error messages

End Try
If you have more than one call to the Execute method, you can surround all of them with one try block as shown in the following code example:
[C#]
try
{
    gp.Execute("Project_management", parameters, null);
    // Some other processes, 
    // for example, repopulate parameters.
    gp.Execute("CopyFeatures_management", parameters, null);
    // Empty and repopulate parameters.
    // 
    gp.Execute("Select_analysis", parameters, null);
    // Get geoprocessing information or warning messages.
}

catch (Exception ex)
{
    // Get exception and geoprocessing error messages.
}
[VB.NET]
Try
gp.Execute("Project_management", parameters, Nothing)
' Some other processes.
' Get geoprocessing information or warning messages.
gp.Execute("CopyFeatures_management", parameters, Nothing)
' Empty and repopulate parameters.
'
gp.Execute("Select_analysis", parameters, Nothing)
' Get geoprocessing information or warning messages.
Catch ex As Exception
' Get exception and geoprocessing error messages.
End Try
In the preceding code example, if the Project tool fails, the CopyFeatures and Select tools are not executed and the flow of control goes to the statements in the catch block. Generally, various tools are run in sequence to chain processes so that output from one tool is used in the next tool. The preceding flow of control ensures no subsequent tool is run once a tool fails.
When you develop your application with the ArcObjects software development kit (SDK) for the Microsoft .NET Framework, you essentially call the Component Object Model (COM) based ArcObjects via COM interops. It is important to identify whether an exception is coming from the COM ArcObjects or from .NET. Broadly, there are two types of exceptions in ArcGIS context. See the following:
  • ArcObjects exceptions—COM exceptions (HRESULT).
  • All other .NET exceptions.
The .NET Framework uses try/catch/finally structured exception handling. The basic structure has one try block, one or more catch blocks, and a finally block.
The following code example shows an elaborate try/catch/finally workflow with several catch blocks, each capturing a specific exception. The catch blocks capture from specific to more general exceptions. The last catch captures the most general System.Exception. The finally block executes in any case.
The following code example tests the robustness of the geoprocessor's Exists method by calling it 100 times in a loop:
[C#]
public void CheckforFeatureClassWithMissing(IGeoProcessor2 gp, string
    catalogPathFeatureClass)
{
    int i = 1;
    bool exists = false;
    for (i == 1; i <= 100; i++)
    {
        object whatever = Type.Missing;
        try
        {
            exists = gp.Exists(catalogPathFeatureClass, ref whatever);
        }
        catch (System.AccessViolationException avEx)
        {
            Console.WriteLine(avEx.Message);
        }
        catch (System.IO.FileLoadException flEx)
        {
            Console.WriteLine(flEx.Message);
        }
        catch (COMException COMex)
        {
            Console.WriteLine(COMex.Message);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
        finally
        {
            Console.WriteLine(string.Format("... Exists is {0} at iteration {1}",
                exists, i.ToString()));
        }
    }
}
[VB.NET]
Public Sub CheckforFeatureClassWithMissing(ByVal gp As IGeoProcessor2, ByVal catalogPathFeatureClass As String)
    
    Dim i As Long = 1
    Dim Exists As Boolean = False
    For i = 1 To 99
        Dim whatever As Object = Type.Missing
        
        Try
        Exists = gp.Exists(catalogPathFeatureClass, whatever)
        Catch avEx As System.AccessViolationException
        Console.WriteLine(avEx.Message)
        Catch flEx As System.IO.FileLoadException
        Console.WriteLine(flEx.Message)
        Catch COMex As COMException
        Console.WriteLine(COMex.Message)
        Catch ex As Exception
        Console.WriteLine(ex.Message)
        Finally
        Console.WriteLine(String.Format("... Exists is {0} at iteration {1}", Exists, i.ToString()))
        End Try
    Next
    
End Sub


See Also:

How to get returned messages
Working with result objects
How to implement error handling
ArcObjects error codes




To use the code in this topic, reference the following assemblies in your Visual Studio project. In the code files, you will need using (C#) or Imports (VB .NET) directives for the corresponding namespaces (given in parenthesis below if different from the assembly name):
  • System.Runtime.InteropServices