Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cosmos EF Core Provider does not throw exception on SaveChangesAsync connection failure #17624

Closed
irontoby opened this issue Sep 4, 2019 · 0 comments · Fixed by #17903

Comments

@irontoby
Copy link

@irontoby irontoby commented Sep 4, 2019

If I call SaveChangesAsync() on a DbContext using the latest 3.0-preview9 provider for CosmosDB, an error in the connection information will not cause an exception to get thrown.

I can see the exception in VS 2019 Preview as $exception in Locals window, which leads me to believe an async call isn't being awaited.

I also tried with preview8 and got the same behavior.

Steps to reproduce

Following are a Program.cs and .csproj to reproduce.

using System;
using System.ComponentModel.DataAnnotations;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

namespace ConsoleApp1
{
    public class Program
    {
        public static async Task Main()
        {
            var host = new HostBuilder()
                .ConfigureHostConfiguration(host => host.SetBasePath(Directory.GetCurrentDirectory()))
                .ConfigureLogging(log => log.AddConsole().AddFilter("Microsoft", LogLevel.None))
                .ConfigureServices(svc => // both these connection strings are designed to fail
                {
                    svc.AddDbContext<SqlContext>(opt => opt.UseSqlServer("Server=none.local;User Id=xxx;Password=xxx;Initial Catalog=xxx;Connect Timeout=1"));
                    svc.AddDbContext<CosmosContext>(opt => opt.UseCosmos("https://contoso.documents.azure.com/", "Y29zbW9zIHBhc3N3b3JkCg==", "SomeDatabase"));
                    svc.AddHostedService<DoStuff>();
                })
                .UseConsoleLifetime()
                .Build();

            await host.RunAsync();
        }
    }

    public class DoStuff : IHostedService
    {
        private readonly SqlContext _sql;
        private readonly CosmosContext _cosmos;
        private readonly ILogger _logger;

        public DoStuff(SqlContext sql, CosmosContext cosmos, ILogger<DoStuff> logger)
        {
            _sql = sql;
            _cosmos = cosmos;
            _logger = logger;
        }

        public async Task StartAsync(CancellationToken cancellationToken)
        {
            var item1 = new Item { Id = Guid.NewGuid(), Name = "Item 1" };
            _sql.Items.Add(item1);

            Task task = null;
            var success = false;

            try
            {
                task = _sql.SaveChangesAsync();
                await task;
                success = true;
            }
            catch (Exception ex)
            {
                _logger.LogError("SQL SaveChangesAsync exception caught: " + ex.Message);
            }

            _logger.LogInformation("SQL SaveChangesAsync " + (success ? "SUCCEEDED" : "FAILED"));
            _logger.LogInformation($"Task Status={task?.Status}, IsFaulted={task?.IsFaulted}");

            var item2 = new Item { Id = Guid.NewGuid(), Name = "Item 2" };
            _cosmos.Items.Add(item2);

            success = false;

            try
            {
                task = _cosmos.SaveChangesAsync();
                await task;
                success = true;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Cosmos SaveChangesAsync exception caught: " + ex.Message);
            }

            _logger.LogInformation("Cosmos SaveChangesAsync " + (success ? "SUCCEEDED" : "FAILED"));
            _logger.LogInformation($"Task Status={task?.Status}, IsFaulted={task?.IsFaulted}");
        }

        public Task StopAsync(CancellationToken cancellationToken)
        {
            return Task.CompletedTask;
        }
    }

    public class SqlContext : DbContext
    {
        public SqlContext(DbContextOptions<SqlContext> options) : base(options) { }
        public DbSet<Item> Items { get; set; }
    }

    public class CosmosContext : DbContext
    {
        public CosmosContext(DbContextOptions<CosmosContext> options) : base(options) { }
        public DbSet<Item> Items { get; set; }
    }

    public class Item
    {
        [Key]
        public Guid Id { get; set; }
        public string Name { get; set; }
    }
}
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp3.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.EntityFrameworkCore.Cosmos" Version="3.0.0-preview9.19423.6" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.0.0-preview9.19423.6" />
    <PackageReference Include="Microsoft.Extensions.Hosting" Version="3.0.0-preview9.19423.4" />
    <PackageReference Include="Microsoft.Extensions.Logging.Console" Version="3.0.0-preview9.19423.4" />
  </ItemGroup>

</Project>

Expected results:

Should receive SaveChangesAsync FAILED for both calls.

Actual results:

> dotnet run
fail: ConsoleApp1.DoStuff[0]
      SQL SaveChangesAsync exception caught: A network-related or instance-specific error occurred [...]
info: ConsoleApp1.DoStuff[0]
      SQL SaveChangesAsync FAILED
info: ConsoleApp1.DoStuff[0]
      Task Status=Faulted, IsFaulted=True
info: ConsoleApp1.DoStuff[0]
      Cosmos SaveChangesAsync SUCCEEDED
info: ConsoleApp1.DoStuff[0]
      Task Status=RanToCompletion, IsFaulted=False

I can see the exception in the VS Locals window:

2019-09-04 18_58_21-Window

Further technical details

EF Core version: 3.0.0-preview9.19423.6
Database Provider: Microsoft.EntityFrameworkCore.Cosmos
Operating system: Windows 10
IDE: Visual Studio 2019 version 16.3.0 Preview 2

@AndriySvyryd AndriySvyryd added this to the 3.1.0 milestone Sep 5, 2019
@AndriySvyryd AndriySvyryd self-assigned this Sep 5, 2019
AndriySvyryd added a commit that referenced this issue Sep 18, 2019
Throw when an error is detected during a store operation.

Fixes #17435
Fixes #17616
Fixes #17624
@AndriySvyryd AndriySvyryd removed their assignment Sep 18, 2019
AndriySvyryd added a commit that referenced this issue Sep 18, 2019
Throw when an error is detected during a store operation.

Fixes #17435
Fixes #17616
Fixes #17624
AndriySvyryd added a commit that referenced this issue Sep 18, 2019
Throw when an error is detected during a store operation.

Fixes #17435
Fixes #17616
Fixes #17624
AndriySvyryd added a commit that referenced this issue Sep 18, 2019
Throw when an error is detected during a store operation.

Fixes #17435
Fixes #17616
Fixes #17624
AndriySvyryd added a commit that referenced this issue Sep 20, 2019
Throw when an error is detected during a store operation.

Fixes #17435
Fixes #17616
Fixes #17624
@ajcvickers ajcvickers modified the milestones: 3.1.0, 3.1.0-preview1 Oct 15, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants
You can’t perform that action at this time.