Improved logging for import errors

This commit is contained in:
Robert McRackan 2022-04-16 16:36:49 -04:00
parent c8c0ffeb0d
commit 5caa9c5687
6 changed files with 44 additions and 24 deletions

View File

@ -3,7 +3,7 @@
<PropertyGroup> <PropertyGroup>
<TargetFramework>net6.0</TargetFramework> <TargetFramework>net6.0</TargetFramework>
<Version>6.7.7.1</Version> <Version>6.7.8.1</Version>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

View File

@ -170,7 +170,7 @@ namespace ApplicationServices
var libraryBookImporter = new LibraryBookImporter(context); var libraryBookImporter = new LibraryBookImporter(context);
var newCount = await Task.Run(() => libraryBookImporter.Import(importItems)); var newCount = await Task.Run(() => libraryBookImporter.Import(importItems));
logTime("importIntoDbAsync -- post Import()"); logTime("importIntoDbAsync -- post Import()");
var qtyChanges = context.SaveChanges(); int qtyChanges = saveChanges(context);
logTime("importIntoDbAsync -- post SaveChanges"); logTime("importIntoDbAsync -- post SaveChanges");
if (qtyChanges > 0) if (qtyChanges > 0)
@ -179,6 +179,27 @@ namespace ApplicationServices
return newCount; return newCount;
} }
private static int saveChanges(LibationContext context)
{
try
{
return context.SaveChanges();
}
catch (Microsoft.EntityFrameworkCore.DbUpdateException ex)
{
// DbUpdateException exceptions can wreck serilog. Condense it until we can find a better solution. I suspect the culpret is the "WithExceptionDetails" serilog extension
static string format(Exception ex) => $"\r\nMessage: {ex.Message}\r\nStack Trace:\r\n{ex.StackTrace}";
var msg = "Microsoft.EntityFrameworkCore.DbUpdateException";
if (ex.InnerException is null)
throw new Exception($"{msg}{format(ex)}");
throw new Exception(
$"{msg}{format(ex)}",
new Exception($"Inner Exception{format(ex.InnerException)}"));
}
}
#endregion #endregion
#region remove books #region remove books

View File

@ -18,7 +18,7 @@ namespace DataLayer
public class Category public class Category
{ {
// Empty is a special case. use private ctor w/o validation // Empty is a special case. use private ctor w/o validation
public static Category GetEmpty() => new Category { CategoryId = -1, AudibleCategoryId = "", Name = "" }; public static Category GetEmpty() => new() { CategoryId = -1, AudibleCategoryId = "", Name = "" };
internal int CategoryId { get; private set; } internal int CategoryId { get; private set; }
public string AudibleCategoryId { get; private set; } public string AudibleCategoryId { get; private set; }

View File

@ -7,7 +7,7 @@ namespace DataLayer
public class Contributor public class Contributor
{ {
// Empty is a special case. use private ctor w/o validation // Empty is a special case. use private ctor w/o validation
public static Contributor GetEmpty() => new Contributor { ContributorId = -1, Name = "" }; public static Contributor GetEmpty() => new() { ContributorId = -1, Name = "" };
// contributors search links are just name with url-encoding. space can be + or %20 // contributors search links are just name with url-encoding. space can be + or %20
// author search link: /search?searchAuthor=Robert+Bevan // author search link: /search?searchAuthor=Robert+Bevan

View File

@ -121,9 +121,7 @@ namespace DtoImporterService
: item.Categories[1].CategoryId; : item.Categories[1].CategoryId;
// This should properly be SingleOrDefault() not FirstOrDefault(), but FirstOrDefault is defensive // This should properly be SingleOrDefault() not FirstOrDefault(), but FirstOrDefault is defensive
var category var category = DbContext.Categories.Local.FirstOrDefault(c => c.AudibleCategoryId == lastCategory);
= DbContext.Categories.Local.FirstOrDefault(c => c.AudibleCategoryId == lastCategory)
?? Category.GetEmpty();
Book book; Book book;
try try

View File

@ -35,6 +35,9 @@ namespace DtoImporterService
private void loadLocal_categories(List<string> categoryIds) private void loadLocal_categories(List<string> categoryIds)
{ {
// must include default/empty/missing
categoryIds.Add(Category.GetEmpty().AudibleCategoryId);
var localIds = DbContext.Categories.Local.Select(c => c.AudibleCategoryId).ToList(); var localIds = DbContext.Categories.Local.Select(c => c.AudibleCategoryId).ToList();
var remainingCategoryIds = categoryIds var remainingCategoryIds = categoryIds
.Distinct() .Distinct()
@ -42,10 +45,8 @@ namespace DtoImporterService
.ToList(); .ToList();
// load existing => local // load existing => local
// remember to include default/empty/missing
var emptyName = Contributor.GetEmpty().Name;
if (remainingCategoryIds.Any()) if (remainingCategoryIds.Any())
DbContext.Categories.Where(c => remainingCategoryIds.Contains(c.AudibleCategoryId) || c.Name == emptyName).ToList(); DbContext.Categories.Where(c => remainingCategoryIds.Contains(c.AudibleCategoryId)).ToList();
} }
// only use after loading contributors => local // only use after loading contributors => local