mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-02-14 18:47:44 -05:00
Add v2 of the Hosting Service and build nuget packages for it (#675)
* Port v2 of Hosting service to SqlToolsService - Renamed project to .v2 so that existing hosted service isn't impacted - Copied over the CoreServices project which contains ConnectionServiceCore and other reusable services for anything interacting with MSSQL - Ported unit test project across and verified tests run. * Nuget package support for reusable DLLs * Use 1.1 version per Karl's suggestion * Use correct license URL and project URL * Use new SMO packages
This commit is contained in:
99
src/Microsoft.SqlTools.Hosting.v2/Utility/TaskExtensions.cs
Normal file
99
src/Microsoft.SqlTools.Hosting.v2/Utility/TaskExtensions.cs
Normal file
@@ -0,0 +1,99 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.SqlTools.Hosting.Utility
|
||||
{
|
||||
public static class TaskExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds handling to check the Exception field of a task and log it if the task faulted
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This will effectively swallow exceptions in the task chain.
|
||||
/// </remarks>
|
||||
/// <param name="antecedent">The task to continue</param>
|
||||
/// <param name="continuationAction">
|
||||
/// An optional operation to perform after exception handling has occurred
|
||||
/// </param>
|
||||
/// <returns>Task with exception handling on continuation</returns>
|
||||
public static Task ContinueWithOnFaulted(this Task antecedent, Action<Task> continuationAction)
|
||||
{
|
||||
return antecedent.ContinueWith(task =>
|
||||
{
|
||||
// If the task hasn't faulted or has an exception, skip processing
|
||||
if (!task.IsFaulted || task.Exception == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LogTaskExceptions(task.Exception);
|
||||
|
||||
// Run the continuation task that was provided
|
||||
try
|
||||
{
|
||||
continuationAction?.Invoke(task);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Instance.Write(LogLevel.Error, $"Exception in exception handling continuation: {e}");
|
||||
Logger.Instance.Write(LogLevel.Error, e.StackTrace);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds handling to check the Exception field of a task and log it if the task faulted.
|
||||
/// This version allows for async code to be ran in the continuation function.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This will effectively swallow exceptions in the task chain.
|
||||
/// </remarks>
|
||||
/// <param name="antecedent">The task to continue</param>
|
||||
/// <param name="continuationFunc">
|
||||
/// An optional operation to perform after exception handling has occurred
|
||||
/// </param>
|
||||
/// <returns>Task with exception handling on continuation</returns>
|
||||
public static Task ContinueWithOnFaulted(this Task antecedent, Func<Task, Task> continuationFunc)
|
||||
{
|
||||
return antecedent.ContinueWith(task =>
|
||||
{
|
||||
// If the task hasn't faulted or doesn't have an exception, skip processing
|
||||
if (!task.IsFaulted || task.Exception == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LogTaskExceptions(task.Exception);
|
||||
|
||||
// Run the continuation task that was provided
|
||||
try
|
||||
{
|
||||
continuationFunc?.Invoke(antecedent).Wait();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Instance.Write(LogLevel.Error, $"Exception in exception handling continuation: {e}");
|
||||
Logger.Instance.Write(LogLevel.Error, e.StackTrace);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void LogTaskExceptions(AggregateException exception)
|
||||
{
|
||||
// Construct an error message for an aggregate exception and log it
|
||||
StringBuilder sb = new StringBuilder("Unhandled exception(s) in async task:");
|
||||
foreach (Exception e in exception.InnerExceptions)
|
||||
{
|
||||
sb.AppendLine($"{e.GetType().Name}: {e.Message}");
|
||||
sb.AppendLine(e.StackTrace);
|
||||
}
|
||||
Logger.Instance.Write(LogLevel.Error, sb.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user