Skip to content

Commit 6242f0b

Browse files
authored
WI #1622 Add unhandled exception handler. (#1812)
* WI #1622 Add unhandled exception handler. * WI #1622 Enforce with AppDomain and add destructor Co-authored-by: mayanje <jeanchrysostome.mayan@e-i.com>
1 parent 2b7eb5a commit 6242f0b

File tree

3 files changed

+42
-2
lines changed

3 files changed

+42
-2
lines changed

TypeCobol.LanguageServer/JsonRPC/IRPCServer.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,10 @@ public interface IRPCServer
2929
/// Write a trace in the server log file
3030
/// </summary>
3131
void WriteServerLog(string trace);
32+
33+
/// <summary>
34+
/// An Unhandled Exception handler
35+
/// </summary>
36+
UnhandledExceptionEventHandler Handler { get; set; }
3237
}
3338
}

TypeCobol.LanguageServer/JsonRPC/JsonRPCServer.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,11 @@ private void PrepareJsonPRCMessage(JObject jsonMessage)
8181
// Remeber all requests sent and still waiting for a response
8282
private IDictionary<string, ResponseWaitState> responsesExpected = new Dictionary<string, ResponseWaitState>();
8383

84+
/// <summary>
85+
/// An Unhandled Exception handler
86+
/// </summary>
87+
public UnhandledExceptionEventHandler Handler { get; set; }
88+
8489
/// <summary>
8590
/// Send an async request to the client and await later for the response or error
8691
/// </summary>
@@ -166,6 +171,7 @@ private void HandleNotification(string method, JToken parameters)
166171
}
167172
catch(Exception e)
168173
{
174+
Handler?.Invoke(this, new UnhandledExceptionEventArgs(e, false));
169175
WriteServerLog(String.Format("Notification handler for {0} failed : {1}", notificationType.GetType().Name, e.Message));
170176
ResponseResultOrError error = new ResponseResultOrError() { code = ErrorCodes.InternalError, message = e.Message , data = parameters?.ToString() };
171177
Reply(method, error);
@@ -196,6 +202,7 @@ private void HandleRequest(string method, string requestId, JToken parameters)
196202
}
197203
catch(Exception e)
198204
{
205+
Handler?.Invoke(this, new UnhandledExceptionEventArgs(e, false));
199206
ResponseResultOrError error = new ResponseResultOrError() { code = ErrorCodes.InternalError, message = e.Message };
200207
Reply(requestId, error);
201208
}
@@ -259,6 +266,7 @@ private void HandleResponse(string requestId, JToken result, JToken error)
259266
}
260267
catch (Exception e)
261268
{
269+
Handler?.Invoke(this, new UnhandledExceptionEventArgs(e, false));
262270
WriteServerLog(String.Format("Task completion for the response expected by request {0} of type {1} failed : {2}", requestId, requestType.GetType().Name, e.Message));
263271
}
264272
}

TypeCobol.LanguageServer/VsCodeProtocol/LanguageServer.cs

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,15 +41,42 @@ public LanguageServer(IRPCServer rpcServer)
4141

4242
RemoteConsole = new RemoteConsole(rpcServer);
4343
RemoteWindow = new RemoteWindow(rpcServer);
44+
45+
//Track any unhandled exception during rpc communication from the server
46+
rpcServer.Handler += UnhandledExceptionHandler;
47+
//Also enforce with AppDomain unhandled exception handler
48+
AppDomain currentDomain = AppDomain.CurrentDomain;
49+
currentDomain.UnhandledException += UnhandledExceptionHandler;
50+
}
51+
52+
/// <summary>
53+
/// Destructor.
54+
/// </summary>
55+
~LanguageServer()
56+
{
57+
this.RpcServer.Handler -= UnhandledExceptionHandler;
58+
AppDomain currentDomain = AppDomain.CurrentDomain;
59+
currentDomain.UnhandledException -= UnhandledExceptionHandler;
4460
}
4561

4662
// RPC server used to send Remote Procedure Calls to the client
4763
protected IRPCServer RpcServer { get; }
4864

49-
public void NotifyException(Exception e)
65+
/// <summary>
66+
/// Unhandled Exception Event Handler
67+
/// </summary>
68+
/// <param name="sender">Sender of the unhandled exception</param>
69+
/// <param name="e">Tne Exception event argument</param>
70+
private void UnhandledExceptionHandler(object sender, UnhandledExceptionEventArgs e)
71+
{
72+
NotifyException(e.ExceptionObject as Exception);
73+
}
74+
75+
public virtual void NotifyException(Exception e)
5076
{
51-
AnalyticsWrapper.Telemetry.TrackException(e, null);
5277
this.RemoteWindow.ShowErrorMessage(e.Message + "\n" + e.StackTrace);
78+
AnalyticsWrapper.Telemetry.TrackException(e, null);
79+
AnalyticsWrapper.Telemetry.SendMail(e, null, null, null);
5380
}
5481

5582
public void NotifyWarning(string message)

0 commit comments

Comments
 (0)