Edit operation failed. - generic message in ArcGIS Pro SDK

2485
3
06-27-2018 08:09 AM
BillMacPherson
New Contributor III

I'm getting an intermittent error during an editing. This code is running as part of a Pro Add-in that I'm writing.

The error doesn't happen every time this function runs but if I repeatedly run this function it will eventually fail. Sometimes it will take 2 tries and other times it will take 20 ties. When running through Visual Studio it will error more frequently. When running as the compiled Add-in, it takes longer to error.


It fails at the insp.ApplyAsync() call with an error message with the heading "Update Feature Attributes" and the message text of "Edit operation failed.". This is some very generic message.

Edit operation failed.

 Another strange thing is that it doesn't hit my error handling for this initial message but after I close the initial message it will then drop to my error handling.


Part of the application's requirements is that I don't need to prompt the user to save edits.

I've also tried EditOperation combined with SaveEditsAsync() with the same error results.

The feature class is stored in a file geodatabase on my local drive.

ArcGIS Pro 2.0

Does anyone know how to prevent this error or code around it somehow?

internal static async Task<int> UpdateBoundarySubdivisionAttribute(string strSelectedAppNo, string strNewSubdivisions)
{
try
{
await ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(async () =>
{
// Find boundary layer.
var disLayer = ArcGIS.Desktop.Mapping.MapView.Active.Map.FindLayers(Settings.Get("pyp_boundary_layer_name")).FirstOrDefault() as BasicFeatureLayer;

// Search by application number attribute.
var queryFilter = new ArcGIS.Core.Data.QueryFilter();
queryFilter.WhereClause = "APPLICATION_NUMBER = '" + strSelectedAppNo + "'";
var rc = disLayer.Search(queryFilter);

// Create list of oids to update. There should only be one.
var oidSet = new List<long>();
while (rc.MoveNext()) { oidSet.Add(rc.Current.GetObjectID()); }

// Create Inspector.
var insp = new ArcGIS.Desktop.Editing.Attributes.Inspector();
insp.Load(disLayer, oidSet);
insp["SUBDNAME"] = strNewSubdivisions;

// Save edits with no undo. If you want the undo option then use EditOperation().
if (true != await insp.ApplyAsync()) // <-- point of error "Update Feature Attributes" "Edit operation failed."
{
   string ERR_PROC = " UpdateBoundarySubdivisionAttribute() ";
   System.Windows.MessageBox.Show("Error in ApplyAsync() ErrProcedure = " + ERR_PROC + " Unable to save edits the the feature class.", "Update Boundary Subdivision Error", MessageBoxButton.OK, MessageBoxImage.Error);
   return;
}
});

return await Task.FromResult(0);
}
catch (Exception ex)
{
string ERR_PROC = " UpdateBoundarySubdivisionAttribute() ";
System.Windows.MessageBox.Show("ErrProcedure = " + ERR_PROC + ex.Message, "Update Boundary Subdivision Error", MessageBoxButton.OK, MessageBoxImage.Error);
return await Task.FromResult(1); // Return error
}
}

0 Kudos
3 Replies
JohnJones
Esri Contributor

A couple suggestions...

  • You should call Dispose() on your cursor after using it the canonical way of doing this is with the using block.
  • You should verify some rows were found (oidSet isn't empty) before attempting to make an edit.
  • You should verify at least one of these rows doesn't already have this value for "SUBDNAME" set before attempting to make an edit (non-edits may still be reported as 'failed' (well they certainly didn't 'succeed').
  • ApplyAsync on the inspector creates its own edit operation, which is setup to report a failed edit through a modal dialog.  If you want more control over the operation you can create your own...
 var op = new EditOperation();
 // op.ShowModalMessageAfterFailure = false; // This shouldn't be necessary as its the default (but not through inspector.ApplyAsync()
 op.Modify(insp);
 bool succeeded = op.Execute();
  • You shouldn't call MessageBox.Show from the background thread, UI should be reported on the UI thread.
  • This is overly convoluted and non-idiomatic.     return 0; is preferred.
return await Task.FromResult(0);
0 Kudos
BillMacPherson
New Contributor III

John, Thank you for you thoughtful reply and list of suggestions. I was called away to work on another project so I'm just now able to get back to this issue.

I have applied your suggestions to my function (see the revised code below). The result is just the same as before. I'm still getting the same generic "Edit operation failed" that I was getting before and it is still just as random as before. The error still occurs on the insp.ApplyAsync() function call.

I also tried  await insp.LoadAsync() but that didn't help.

Could this be a bug within the inspector.ApplyAsync() function call? If you have any other suggestions, I would appreciate the help.

ArcGIS Pro 2.0, Visual Studio 2017 community edition, file geodatabase.

internal static async Task<int> UpdateBoundarySubdivisionAttribute(string strSelectedAppNo, string strNewSubdivisions)
{
Debug.WriteLine(" UpdateBoundarySubdivisionAttribute() start");
try
{
await ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(async () =>
{
// Find boundary layer.
var disLayer = ArcGIS.Desktop.Mapping.MapView.Active.Map.FindLayers(Settings.Get("pyp_boundary_layer_name")).FirstOrDefault() as BasicFeatureLayer;

// Search by application number attribute.
var queryFilter = new ArcGIS.Core.Data.QueryFilter
{
WhereClause = "APPLICATION_NUMBER = '" + strSelectedAppNo + "'"
};

// Add each ObjectID to the List.
var oidSet = new List<long>();
using (RowCursor rc = disLayer.Search(queryFilter))
{
while (rc.MoveNext())
{
oidSet.Add(rc.Current.GetObjectID());
}
}

// There should be one ObjectID - boundary feature.
if (oidSet.Count < 1)
{
// This shouldn't happen. There should always be one boundary feature for this AppNo.
return;
}

// Create Inspector.
ArcGIS.Desktop.Editing.Attributes.Inspector insp = new ArcGIS.Desktop.Editing.Attributes.Inspector();

insp.Load(disLayer, oidSet);

insp["SUBDNAME"] = strNewSubdivisions;

if (true != await insp.ApplyAsync())
{
return; // Return error
}
});

// Return success
return 0;
}
catch (Exception ex)
{
string ERR_PROC = " UpdateBoundarySubdivisionAttribute() ";
System.Windows.MessageBox.Show("ErrProcedure = " + ERR_PROC + ex.Message, "Update Boundary Subdivision Error", MessageBoxButton.OK, MessageBoxImage.Error);
return 1; // Return error
}
}

NarelleChedzey
Esri Contributor

As you are seeing the issue with a file geodatabase is there any chance you can post your data (or a subset where you can still duplicate the sporadic problem)? Similarly with your entire add-in code. ?

If the data and/or code is proprietary I understand if you can't post it, but it may help us duplicate the problem a little more quickly. 

Right now we've identified one data locking issue which returns the 'edit operation failed' rather than something more specific.  But it is not a sporadic problem and can be reproduced with a clear set of steps.   We are working on resolving this issue but it's unclear whether your problem is a data locking issue or something else.   The data and code along with some reproducible steps (even for a sporadic problem)  will help us with trying to track down your problem. 

Thanks

Narelle

0 Kudos