簡體   English   中英

虛擬異常停止執行子方法,但不會冒泡

[英]Phantom exception stops execution of child method, but doesn't bubble up

我有一個響應於SNS消息而執行的AWS lambda函數。 有一些莫名其妙的行為發生,子方法突然停止執行(好像引發了異常),但是父方法此后繼續正常執行。

public void InsertEntity(Entity entity)
{
    _context.Entities.Add(entity);

    _logger.Log($"Before SaveChanges, entity.Id is {entity.Id}");

    _context.SaveChanges();

    _logger.Log($"After SaveChanges, entity.Id is {entity.Id}");

    if (entity.Id < 0)
        throw new Exception($"InsertEntity succeeded, but id is invalid: {entity.Id}");
}

public int? ImportEntity(string xml)
{
    var entity = new Entity(xml);

    _entityRepository.InsertEntity(entity);

    _logger.LogLine($"Entity inserted successfully with Id {entity.Id}");

    return entity.Id;
}

在這種情況下,上下文是使用PostgreSQL EF提供程序的標准DbContext。

首次創建實體時,Id為0。將其添加到上下文DbSet中時,id變為一個臨時負整數,如-2147392341 在調用SaveChanges之后,應從數據庫中為實體賦予一個ID,即一個正數。

此處的任何異常都應包含到調用ImportEntity的方法中,並應處理錯誤。 相反,我在AWS中的日志文件如下所示:

Before SaveChanges, entity.Id is -2147482647
Entity inserted successfully with Id -2147482647

負值將被返回,並且在任何時候都不會引發異常。 由於我在InsertEntity中有專門檢查負值的代碼,因此我唯一看到的可能性是SaveChanges引發了一個異常,該異常導致日志記錄和否定檢查都無法運行。 但是父方法如何繼續記錄和執行並返回值?

我知道我的代碼正在AWS上更新,因為我最近添加了“ SaveChanges”日志,並且該日志正在顯示,並且我同時添加了所有日志。

編輯

我直接在_context.SaveChanges();周圍添加了try / catch _context.SaveChanges(); 並能夠捕獲潛在的異常。 問題仍然是,為什么/如何在ImportEntity函數中繼續執行,即使從InsertEntity中拋出異常也是如此。

編輯2

添加csproj定義:

<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
    <TargetFramework>netcoreapp2.0</TargetFramework>
    <AssemblyName>MyService</AssemblyName>
    <OutputType>Library</OutputType>
    <PackageId>MyService</PackageId>
    <GenerateAssemblyTitleAttribute>false</GenerateAssemblyTitleAttribute>
    <GenerateAssemblyDescriptionAttribute>false</GenerateAssemblyDescriptionAttribute>
    <GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
    <GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
    <GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
    <GenerateAssemblyCopyrightAttribute>false</GenerateAssemblyCopyrightAttribute>
    <GenerateAssemblyVersionAttribute>false</GenerateAssemblyVersionAttribute>
    <GenerateAssemblyFileVersionAttribute>false</GenerateAssemblyFileVersionAttribute>
</PropertyGroup>
<ItemGroup>
    <None Update="runtimes\linux\lib\netstandard1.3\System.Net.NetworkInformation.dll">
    <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
    </None>
</ItemGroup>
<ItemGroup>
    <PackageReference Include="Amazon.Lambda.Core" Version="1.0.0" />
    <PackageReference Include="AWSSDK.S3" Version="3.3.16.2" />
    <PackageReference Include="Amazon.Lambda.Serialization.Json" Version="1.1.0" />
    <PackageReference Include="Amazon.Lambda.S3Events" Version="1.0.2" />
    <PackageReference Include="AWSSDK.XRay" Version="3.3.1.6" />
    <PackageReference Include="AWSXRayRecorder" Version="2.0.0-beta" />
    <PackageReference Include="AWSXRayRecorder.Handlers.AwsSdk" Version="2.0.0-beta" />
    <PackageReference Include="Castle.Core" Version="4.2.1" />
    <PackageReference Include="Microsoft.Extensions.Configuration" Version="2.0.0" />
    <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.0.0" />
    <PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="2.0.0" />
    <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="2.0.1" />
    <PackageReference Include="HtmlAgilityPack.NetCore" Version="1.5.0.1" />
    <PackageReference Include="Amazon.Lambda.SNSEvents" Version="1.0.0" />
    <PackageReference Include="System.Net.NetworkInformation" Version="4.3.0" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="2.0.1" />
    <PackageReference Include="Autofac.Extensions.DependencyInjection" Version="4.2.0" />
    <PackageReference Include="AWSSDK.SimpleNotificationService" Version="3.3.0.24" />
</ItemGroup>
<ItemGroup>
    <DotNetCliToolReference Include="Amazon.Lambda.Tools" Version="2.1.0" />
</ItemGroup>
</Project>

以及AWS調用的頂級lambda方法,然后調用ImportEntity:

public void ProcessEntity(SNSEvent evnt, ILambdaContext context)
{
    var fileContent = GetFileContent(evnt);

    using (var lifetimeScope = Container.BeginLifetimeScope())
    {
        var processor = processingScope.Resolve<IEntityProcessor>();
        var result = processor.ImportEntity(fileContent);

        context.Logger.LogLine($"Successfully imported entity, Id is {result.Value}");
        return result;
    }
}

這個問題以前已經見過很多次了。 我懷疑根本原因與未等待的異步進程引發異常時發生的情況類似:它們不會冒泡到您的代碼,因為它們並非旨在這樣做。

在其他情況下,此類問題已解決,則根故障通常在代碼外部,這意味着數據庫連接,映射中的某個位置,甚至在數據庫端本身。 發生這種情況時,線程會簡單地死掉並繼續執行,就像SaveChanges已正常返回一樣。

數據庫超時可能會導致此行為。 類似於POCO文件的文件與數據庫不正確一樣,也可能導致該文件,並且您可能不會收到警告。 32位和64位文件位置之間的混亂可能會導致這種情況。 如果數據庫是事務性的,臟的ObjectStateEntry對象無法持久保存,則任何事務失敗都會導致這種情況。

我將從查看數據庫上的錯誤日志開始-令人驚訝的是,當您這樣做時,問題變得如此明顯的頻率。 如果日志未顯示問題,則將工具放在數據庫端,然后查看接收到的查詢,查詢結果和查詢執行。 那很可能會指出正確的方向。

如果這不能使您暢通無阻,則值得花時間進行完整且可執行的最小化復制並發布。 這將為我提供尋找問題根源所需的一切。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM