From 5f009deef63a8490d0a1fe1c24786986112efd40 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Janis=20Daniel=20Da=CC=88hne?=
 <janis.daehne2@student.uni-halle.de>
Date: Tue, 19 Nov 2019 22:39:01 +0100
Subject: [PATCH] - added exception helper that logs and formats exceptions   -
 it will also output a guid that the frontend can display and the admin can
 look into the console and search for the guid - reduced extensive logging
 output to frontend (only logged to console)

---
 src/ClientServer/Config/Constants.cs          |  2 +-
 .../Controllers/ControllerWithDb.cs           |  4 +-
 .../Core/Exercises/SubmissionController.cs    |  6 ++-
 .../Core/Testing/TestingController.cs         | 37 +++++++++++--------
 src/ClientServer/Helpers/ExceptionHelper.cs   | 25 +++++++++++++
 5 files changed, 53 insertions(+), 21 deletions(-)
 create mode 100644 src/ClientServer/Helpers/ExceptionHelper.cs

diff --git a/src/ClientServer/Config/Constants.cs b/src/ClientServer/Config/Constants.cs
index d1aae06..5180109 100644
--- a/src/ClientServer/Config/Constants.cs
+++ b/src/ClientServer/Config/Constants.cs
@@ -13,7 +13,7 @@ namespace ClientServer.Helpers
     /// </summary>
     public static class Constants
     {
-        public static string VersionString = "2.6.0";
+        public static string VersionString = "2.6.1";
 
         /// <summary>
         /// this is only set once at program.cs!!
diff --git a/src/ClientServer/Controllers/ControllerWithDb.cs b/src/ClientServer/Controllers/ControllerWithDb.cs
index ff2bc63..706801b 100644
--- a/src/ClientServer/Controllers/ControllerWithDb.cs
+++ b/src/ClientServer/Controllers/ControllerWithDb.cs
@@ -32,12 +32,12 @@ namespace ClientServer.Controllers
         public Task HandleDbError(Exception ex)
         {
             //Exception.toString() is more verbose than just the exception + inner...
-            Console.WriteLine("[DB ERROR]: " + ex);
+            string errorMsg = ExceptionHelper.GetAndLogException(ex, "server db error");
             
             if (AppConfiguration.IsDebugMode)
             {
                 return
-                    Response.WriteAsync(Jc.Serialize(new BasicResponse(ResponseCode.ServerError, ex.Message)));
+                    Response.WriteAsync(Jc.Serialize(new BasicResponse(ResponseCode.ServerError, errorMsg)));
             }
 
             return
diff --git a/src/ClientServer/Controllers/Core/Exercises/SubmissionController.cs b/src/ClientServer/Controllers/Core/Exercises/SubmissionController.cs
index c2fb058..8bcb719 100644
--- a/src/ClientServer/Controllers/Core/Exercises/SubmissionController.cs
+++ b/src/ClientServer/Controllers/Core/Exercises/SubmissionController.cs
@@ -1037,12 +1037,14 @@ namespace ClientServer.Controllers.Core.Exercises
             catch (System.Exception ex)
             {
 
+                string errorMessage =
+                    ExceptionHelper.GetAndLogException(ex, "could not process line " + lineCount + ", error: ");
+
                 if (AppConfiguration.IsDebugMode)
                 {
                     await
                         Response.WriteAsync(
-                            Jc.Serialize(new BasicResponse(ResponseCode.InvalidRequest,
-                                "could not process line " + lineCount + ", error: " + ex)));
+                            Jc.Serialize(new BasicResponse(ResponseCode.InvalidRequest, errorMessage)));
                 }
                 else
                 {
diff --git a/src/ClientServer/Controllers/Core/Testing/TestingController.cs b/src/ClientServer/Controllers/Core/Testing/TestingController.cs
index 83483bc..36b12ee 100644
--- a/src/ClientServer/Controllers/Core/Testing/TestingController.cs
+++ b/src/ClientServer/Controllers/Core/Testing/TestingController.cs
@@ -228,7 +228,6 @@ namespace ClientServer.Controllers.Core.Testing
                 return;
             }
 
-
             await _WriteCompileTestResult(answerFromTestServer);
         }
 
@@ -551,7 +550,6 @@ namespace ClientServer.Controllers.Core.Testing
                 return;
             }
 
-
             await _WriteCompileTestResult(answerFromTestServer);
         }
 
@@ -1442,10 +1440,12 @@ namespace ClientServer.Controllers.Core.Testing
             catch (Exception ex)
             {
                 //we create this exception so it should be ok to send just the message...
-                Console.WriteLine("ERROR creating tests with test files: " + ex);
+
+                string errorMessage = ExceptionHelper.GetAndLogException(ex, "ERROR creating tests with test files");
+                
                 await
                     Response.WriteAsync(
-                        Jc.Serialize(new BasicResponse(ResponseCode.NotFound, ex.Message)));
+                        Jc.Serialize(new BasicResponse(ResponseCode.NotFound, errorMessage)));
                 return;
             }
 
@@ -1823,10 +1823,10 @@ namespace ClientServer.Controllers.Core.Testing
                 catch (Exception ex)
                 {
                     //we create this exception so it should be ok to send just the message...
-                    Console.WriteLine("ERROR creating tests with test files: " + ex);
+                    string errorMessage = ExceptionHelper.GetAndLogException(ex, "ERROR creating tests with test files");
                     await
                         Response.WriteAsync(
-                            Jc.Serialize(new BasicResponse(ResponseCode.NotFound, ex.Message)));
+                            Jc.Serialize(new BasicResponse(ResponseCode.NotFound, errorMessage)));
                     return;
                 }
                 
@@ -2009,10 +2009,10 @@ namespace ClientServer.Controllers.Core.Testing
                 catch (Exception ex)
                 {
                     //we create this exception so it should be ok to send just the message...
-                    Console.WriteLine("ERROR creating tests with test files: " + ex);
+                    string errorMessage = ExceptionHelper.GetAndLogException(ex, "ERROR creating tests with test files");
                     await
                         Response.WriteAsync(
-                            Jc.Serialize(new BasicResponse(ResponseCode.NotFound, ex.Message)));
+                            Jc.Serialize(new BasicResponse(ResponseCode.NotFound, errorMessage)));
                     return;
                 }
 
@@ -2251,10 +2251,10 @@ namespace ClientServer.Controllers.Core.Testing
             catch (Exception ex)
             {
                 //we create this exception so it should be ok to send just the message...
-                Console.WriteLine("ERROR creating tests with test files: " + ex);
+                string errorMessage = ExceptionHelper.GetAndLogException(ex, "ERROR creating tests with test files");
                 await
                     Response.WriteAsync(
-                        Jc.Serialize(new BasicResponse(ResponseCode.NotFound, ex.Message)));
+                        Jc.Serialize(new BasicResponse(ResponseCode.NotFound, errorMessage)));
                 return;
             }
 
@@ -2448,10 +2448,10 @@ namespace ClientServer.Controllers.Core.Testing
             catch (Exception ex)
             {
                 //we create this exception so it should be ok to send just the message...
-                Console.WriteLine("ERROR creating tests with test files: " + ex);
+                string errorMessage = ExceptionHelper.GetAndLogException(ex, "ERROR creating tests with test files");
                 await
                     Response.WriteAsync(
-                        Jc.Serialize(new BasicResponse(ResponseCode.NotFound, ex.Message)));
+                        Jc.Serialize(new BasicResponse(ResponseCode.NotFound, errorMessage)));
                 return;
             }
             
@@ -2832,10 +2832,10 @@ namespace ClientServer.Controllers.Core.Testing
             catch (Exception ex)
             {
                 //we create this exception so it should be ok to send just the message...
-                Console.WriteLine("ERROR creating tests with test files: " + ex);
+                string errorMessage = ExceptionHelper.GetAndLogException(ex, "ERROR creating tests with test files");
                 await
                     Response.WriteAsync(
-                        Jc.Serialize(new BasicResponse(ResponseCode.NotFound, ex.Message)));
+                        Jc.Serialize(new BasicResponse(ResponseCode.NotFound, errorMessage)));
                 return;
             }
 
@@ -3246,11 +3246,16 @@ namespace ClientServer.Controllers.Core.Testing
                     else
                     {
                         //not a task timeout exception... get some more info 
-                        Console.WriteLine("ERROR getting test server result: " + ex);
+
+                        string errorDescription = "error during connecting to test server";
+                        string errorMessage =
+                            ExceptionHelper.GetAndLogException(ex, errorDescription);
+                        
+                        errorMessageDuringRequest = errorDescription;
 
                         if (AppConfiguration.IsDebugMode)
                         {
-                            errorMessageDuringRequest = "error during connecting to test server: " + ex;
+                            errorMessageDuringRequest = errorMessage;
                         }
                     }                 
                 }
diff --git a/src/ClientServer/Helpers/ExceptionHelper.cs b/src/ClientServer/Helpers/ExceptionHelper.cs
new file mode 100644
index 0000000..515195e
--- /dev/null
+++ b/src/ClientServer/Helpers/ExceptionHelper.cs
@@ -0,0 +1,25 @@
+using System;
+
+namespace ClientServer.Helpers
+{
+    public static class ExceptionHelper
+    {
+        /// <summary>
+        /// a full stack trace might be too much for debug mode... just return exception message and first inner exception
+        /// the full stack trace should be logged to the console
+        ///
+        /// this should be only called if <see cref="AppConfiguration.IsDebugMode"/> is true! else a generic error string should be returned e.g. only db server error
+        /// </summary>
+        /// <param name="ex"></param>
+        /// <param name="errorDescription">some description e.g. db error or the file name to be logged to the console</param>
+        /// <returns></returns>
+        public static string GetAndLogException(Exception ex, string errorDescription)
+        {
+
+            var exceptionGuid = Guid.NewGuid().ToString();
+            Console.WriteLine($"[{errorDescription}] - {exceptionGuid} - " + ex);
+            
+            return  "[" + errorDescription + "] - guid: " + exceptionGuid + " - " + ex.Message + " | " + (ex.InnerException != null ? ex.InnerException.Message : "");
+        }
+    }
+}
-- 
GitLab