Catch Request/Event handler errors at dispatcher level (#1610)

* Catch Request/Event handler errors at dispatcher level

* Fix tests

* Use Exception overload of SendError

* Fix tests
This commit is contained in:
Charles Gagnon
2022-07-29 17:31:36 -07:00
committed by GitHub
parent 3294a52ad9
commit fd00114a0e
32 changed files with 1326 additions and 1921 deletions

View File

@@ -115,55 +115,48 @@ namespace Microsoft.SqlTools.ServiceLayer.Profiler
/// </summary>
internal async Task HandleCreateXEventSessionRequest(CreateXEventSessionParams parameters, RequestContext<CreateXEventSessionResult> requestContext)
{
try
ConnectionInfo connInfo;
ConnectionServiceInstance.TryFindConnection(
parameters.OwnerUri,
out connInfo);
if (connInfo == null)
{
ConnectionInfo connInfo;
ConnectionServiceInstance.TryFindConnection(
parameters.OwnerUri,
out connInfo);
if (connInfo == null)
{
throw new Exception(SR.ProfilerConnectionNotFound);
}
else if (parameters.SessionName == null)
{
throw new ArgumentNullException("SessionName");
}
else if (parameters.Template == null)
{
throw new ArgumentNullException("Template");
}
else
{
IXEventSession xeSession = null;
// first check whether the session with the given name already exists.
// if so skip the creation part. An exception will be thrown if no session with given name can be found,
// and it can be ignored.
try
{
xeSession = this.XEventSessionFactory.GetXEventSession(parameters.SessionName, connInfo);
}
catch { }
if (xeSession == null)
{
// create a new XEvent session and Profiler session
xeSession = this.XEventSessionFactory.CreateXEventSession(parameters.Template.CreateStatement, parameters.SessionName, connInfo);
}
// start monitoring the profiler session
monitor.StartMonitoringSession(parameters.OwnerUri, xeSession);
var result = new CreateXEventSessionResult();
await requestContext.SendResult(result);
SessionCreatedNotification(parameters.OwnerUri, parameters.SessionName, parameters.Template.Name);
}
throw new Exception(SR.ProfilerConnectionNotFound);
}
catch (Exception e)
else if (parameters.SessionName == null)
{
await requestContext.SendError(new Exception(SR.CreateSessionFailed(e.Message)));
throw new ArgumentNullException("SessionName");
}
else if (parameters.Template == null)
{
throw new ArgumentNullException("Template");
}
else
{
IXEventSession xeSession = null;
// first check whether the session with the given name already exists.
// if so skip the creation part. An exception will be thrown if no session with given name can be found,
// and it can be ignored.
try
{
xeSession = this.XEventSessionFactory.GetXEventSession(parameters.SessionName, connInfo);
}
catch { }
if (xeSession == null)
{
// create a new XEvent session and Profiler session
xeSession = this.XEventSessionFactory.CreateXEventSession(parameters.Template.CreateStatement, parameters.SessionName, connInfo);
}
// start monitoring the profiler session
monitor.StartMonitoringSession(parameters.OwnerUri, xeSession);
var result = new CreateXEventSessionResult();
await requestContext.SendResult(result);
SessionCreatedNotification(parameters.OwnerUri, parameters.SessionName, parameters.Template.Name);
}
}
@@ -172,30 +165,23 @@ namespace Microsoft.SqlTools.ServiceLayer.Profiler
/// </summary>
internal async Task HandleStartProfilingRequest(StartProfilingParams parameters, RequestContext<StartProfilingResult> requestContext)
{
try
ConnectionInfo connInfo;
ConnectionServiceInstance.TryFindConnection(
parameters.OwnerUri,
out connInfo);
if (connInfo != null)
{
ConnectionInfo connInfo;
ConnectionServiceInstance.TryFindConnection(
parameters.OwnerUri,
out connInfo);
if (connInfo != null)
{
// create a new XEvent session and Profiler session
var xeSession = this.XEventSessionFactory.GetXEventSession(parameters.SessionName, connInfo);
// start monitoring the profiler session
monitor.StartMonitoringSession(parameters.OwnerUri, xeSession);
// create a new XEvent session and Profiler session
var xeSession = this.XEventSessionFactory.GetXEventSession(parameters.SessionName, connInfo);
// start monitoring the profiler session
monitor.StartMonitoringSession(parameters.OwnerUri, xeSession);
var result = new StartProfilingResult();
await requestContext.SendResult(result);
}
else
{
throw new Exception(SR.ProfilerConnectionNotFound);
}
var result = new StartProfilingResult();
await requestContext.SendResult(result);
}
catch (Exception e)
else
{
await requestContext.SendError(new Exception(SR.StartSessionFailed(e.Message)));
throw new Exception(SR.ProfilerConnectionNotFound);
}
}
@@ -204,43 +190,36 @@ namespace Microsoft.SqlTools.ServiceLayer.Profiler
/// </summary>
internal async Task HandleStopProfilingRequest(StopProfilingParams parameters, RequestContext<StopProfilingResult> requestContext)
{
try
{
ProfilerSession session;
monitor.StopMonitoringSession(parameters.OwnerUri, out session);
ProfilerSession session;
monitor.StopMonitoringSession(parameters.OwnerUri, out session);
if (session != null)
if (session != null)
{
// Occasionally we might see the InvalidOperationException due to a read is
// in progress, add the following retry logic will solve the problem.
int remainingAttempts = 3;
while (true)
{
// Occasionally we might see the InvalidOperationException due to a read is
// in progress, add the following retry logic will solve the problem.
int remainingAttempts = 3;
while (true)
try
{
try
session.XEventSession.Stop();
await requestContext.SendResult(new StopProfilingResult { });
break;
}
catch (InvalidOperationException)
{
remainingAttempts--;
if (remainingAttempts == 0)
{
session.XEventSession.Stop();
await requestContext.SendResult(new StopProfilingResult { });
break;
}
catch (InvalidOperationException)
{
remainingAttempts--;
if (remainingAttempts == 0)
{
throw;
}
Thread.Sleep(500);
throw;
}
Thread.Sleep(500);
}
}
else
{
throw new Exception(SR.SessionNotFound);
}
}
catch (Exception e)
else
{
await requestContext.SendError(new Exception(SR.StopSessionFailed(e.Message)));
throw new Exception(SR.SessionNotFound);
}
}
@@ -249,16 +228,9 @@ namespace Microsoft.SqlTools.ServiceLayer.Profiler
/// </summary>
internal async Task HandlePauseProfilingRequest(PauseProfilingParams parameters, RequestContext<PauseProfilingResult> requestContext)
{
try
{
monitor.PauseViewer(parameters.OwnerUri);
monitor.PauseViewer(parameters.OwnerUri);
await requestContext.SendResult(new PauseProfilingResult { });
}
catch (Exception e)
{
await requestContext.SendError(new Exception(SR.PauseSessionFailed(e.Message)));
}
await requestContext.SendResult(new PauseProfilingResult { });
}
/// <summary>
@@ -266,27 +238,20 @@ namespace Microsoft.SqlTools.ServiceLayer.Profiler
/// </summary>
internal async Task HandleGetXEventSessionsRequest(GetXEventSessionsParams parameters, RequestContext<GetXEventSessionsResult> requestContext)
{
try
var result = new GetXEventSessionsResult();
ConnectionInfo connInfo;
ConnectionServiceInstance.TryFindConnection(
parameters.OwnerUri,
out connInfo);
if (connInfo == null)
{
var result = new GetXEventSessionsResult();
ConnectionInfo connInfo;
ConnectionServiceInstance.TryFindConnection(
parameters.OwnerUri,
out connInfo);
if (connInfo == null)
{
await requestContext.SendError(new Exception(SR.ProfilerConnectionNotFound));
}
else
{
List<string> sessions = GetXEventSessionList(parameters.OwnerUri, connInfo);
result.Sessions = sessions;
await requestContext.SendResult(result);
}
await requestContext.SendError(new Exception(SR.ProfilerConnectionNotFound));
}
catch (Exception e)
else
{
await requestContext.SendError(e);
List<string> sessions = GetXEventSessionList(parameters.OwnerUri, connInfo);
result.Sessions = sessions;
await requestContext.SendResult(result);
}
}
@@ -295,14 +260,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Profiler
/// </summary>
internal async Task HandleDisconnectSessionRequest(DisconnectSessionParams parameters, RequestContext<DisconnectSessionResult> requestContext)
{
try
{
monitor.StopMonitoringSession(parameters.OwnerUri, out _);
}
catch (Exception e)
{
await requestContext.SendError(e);
}
monitor.StopMonitoringSession(parameters.OwnerUri, out _);
}
/// <summary>