Hi,
We are getting issue with Exceptions while using ABP InsertSync.
For any error/exception came from SQL not getting moved in exception code and not going in catch statement.
This is happening whenever we are passing false in Repository.InsertAsync().
As shown below in Option 1 code. Please suggest, we need to send custom error number like - throw new CivitException(ex.Message, "2601");
Same is working fine if we are calling direct EfCoreException
-------------------------------------------------------------------- +@ AbpException Code starts -------------------------------------------------------------------- //Option1 :- passing inner async parameter as "false".
public async Task AddOrganization(OrganizationDto input)
{
try
{
var data = ObjectMapper.Map<OrganizationDto, Setup.Organization.Organization>(input);
await _orgContactRepository.InsertAsync(data, false);
}
catch (DbUpdateException ex)
{
throw new CivitException(ex.Message, "2601");
}
}
//Option2 :- passing inner async parameter as "true"
public async Task AddOrganization(OrganizationDto input)
{
try
{
var data = ObjectMapper.Map<OrganizationDto, Setup.Organization.Organization>(input);
await _orgContactRepository.InsertAsync(data, true);
}
catch (DbUpdateException ex)
{
throw new CivitException(ex.Message, "2601");
}
}
------------------------------------ +@ AbpException Code Ends --------------------------------------------------------------------
----------------------------------- +@ EFCoreException Code starts --------------------------------------------------------------------
public override int SaveChanges()
{
try
{
var data=base.SaveChanges();
return data;
}
catch (DbUpdateException e)
{
Console.WriteLine(e);
throw;
}
}
------------------------------------------------ +@ EFCoreException Code ends --------------------------------------------------------------------
5 Answer(s)
-
0
What's the stacktrace? You haven't mentioned about the exception
-
0
What's the stacktrace? You haven't mentioned about the exception
Do you need stacktrace? Situation in Steps-
- Calling InsertSync() function and Passing False as parameter {as mentioned in below sample code}
- If any exception comes then it should go to Catch{} loop.
- But currently it is not going.
- If we are using plain 'DbUpdateException' of EFCore, then it is raising Ex.message {Sample code added in Previou/ above message}
public async Task AddOrganization(OrganizationDto input) { try { var data = ObjectMapper.Map<OrganizationDto, Setup.Organization.Organization>(input); ~~await _orgContactRepository.InsertAsync(data, false);~~ } **catch (DbUpdateException ex) { throw new CivitException(ex.Message, "2601"); }** }
-
0
This is EF Core default behaviour. When there's DbUpdateException, the default exception handler only handles
An internal error occurred during your request
. If you need the details of the exception you need to cast it, or you need to catchDbUpdateException
. Check out this https://stackoverflow.com/questions/22490842/finding-the-reason-for-dbupdateexceptiontry { await _orgContactRepository.InsertAsync(data, false); } catch (DbEntityValidationException vex) { var exception = HandleDbEntityValidationException(vex); throw new UserFriendlyException("Ooppps! This record is not valid.."); } catch(DbUpdateException dbu) { var builder = new StringBuilder("A DbUpdateException was caught while saving changes."); try { foreach (var result in dbu.Entries) { builder.AppendFormat("Type: {0} was part of the problem. ", result.Entity.GetType().Name); } } catch (Exception e) { builder.Append("Error parsing DbUpdateException: " + e.ToString()); } string message = builder.ToString(); return new Exception(message, dbu); throw new UserFriendlyException("Ooppps! Error occured while saving the record."); }
-
1
My previous code will also not work in your case. I'll explain the structure, why it doesn't work as you expect and what you can do for a solution;
PROBLEM:
The below code executes
InsertAsync
method withsaveChanges=false
. This means the entityorg
will be set as inserted record to the EF Core tracking system. At this point no real insert operation is done. So you'll leave the method without getting any exception because still no database operations has been done. Right after you leave the method, the framework callsSaveChanges
method of the EF Core's DbContext class. It discovers any changes to the entity instances and applies to the database. And you get exception at this point. But you already left the try-catch block andHTTP-500: An internal error occured
exception will be thrown to the UI.public async Task AddOrganizationAsync(Organization org) { try { await _organizationRepository.InsertAsync(org, false); } catch (DbUpdateException ex) { throw new MyCustomException(ex.Message, "2601"); } }
SOLUTION:
If you want to catch the exception in a try-catch block you need to save the changes before leaving the try-catch block. If you have several database operations you can call
SaveChanges
one time when you finish all the database operations.public async Task AddOrganizationAsync(Organization org) { try { await _organizationRepository.InsertAsync(org, false); await _organizationMemberRepository.InsertAsync(org.Members, false); await _organizationInvoices.UpdateAsync(org.Invoices, false); await _organizationStatistics.DeleteAsync(org.DeletedSomeId); //and other DB operations... //apply changes to the database, you can handle exception at this point await UnitOfWorkManager.Current.SaveChangesAsync(); } catch (DbUpdateException ex) { throw new MyCustomException(ex.Message, "2601"); } }
Documents:
- https://docs.abp.io/en/abp/latest/Unit-Of-Work#savechangesasync
- https://docs.microsoft.com/en-us/dotnet/api/microsoft.entityframeworkcore.dbcontext.savechanges?view=efcore-5.0
-
0
This question has been automatically marked as stale because it has not had recent activity.