I have a problem with the error handling in a custom EditOperation for ArcGIS Pro application I am building.
The EditOperation is constructed using a series of operations which are added using the EditOperation.Callback() method. If some problem occurs during execution I would like to have general error handling but for some reason this does not work when the data is located enterprise geodatabase (SQL server). On the contrary it leads to ArcGIS Pro Crash. Here is a small code example that illustrates the issue. It is a very simple example where the function SmallDemoCall(table, idList) would just delete some records from the provided table if the value in a column called “ID” equals values from the provided idList.
However, if the provided idList is without values an illegal SQL is generated and the EditOperation.ExecuteAsync() leads to an ArcGIS Pro crash.
So my question is: Is this code faulty and in that case how should general error handling for EditOperations then be achieved?
public class EditOperationCallbackTest
{
public async Task SmallDemoCall(Table myDataTable, List<int> idList)
{
try
{
EditOperation deleteOperation = new EditOperation()
{
SelectNewFeatures = false,
EditOperationType = EditOperationType.Long,
Name = "Delete elements",
ExecuteMode = ExecuteModeType.Sequential,
ShowModalMessageAfterFailure = false
};
// if idList is empty this result in whereClause being whereClause = "ID IN ()" - which is not valid sql
// it could easily be fixed - but this is not really the point.
// The general error handling should cope with this as all kind of issues could rise during the data modification
string whereClause = $"ID IN ({string.Join(", ", idList.Distinct().ToString())})";
await DeleteInternalAsync(myDataTable, whereClause, deleteOperation);
// if the whereClause is invalid and myDatatTable points to table in an SQL sever enterprise geodatabase this leads to a ArcGIS Pro crash.
// however for an invalid whereclause combined with a table from a file geodatabase (*.gdb) the error handling seems to work
await deleteOperation.ExecuteAsync();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
private async Task DeleteInternalAsync(Table table, string whereClause, EditOperation editOperation)
{
await QueuedTask.Run(() =>
{
QueryFilter qf = new QueryFilter();
qf.WhereClause = whereClause;
editOperation.Callback(context =>
{
using (var cursor = table.Search(qf, false))
{
while (cursor.MoveNext())
{
using (var row = cursor.Current)
{
context.Invalidate(row);
row.Delete();
}
}
}
}, table);
});
}