public void TrackErrorWithObfuscateUserName() { // Prepared data. Constants.UserName = "******"; var semaphore = new SemaphoreSlim(0); var stacktraceWithUserName = $"C:\\{Constants.UserName}\\some\\path;\nC:\\test\\{Constants.UserName}\\some\\path;\nC:\\no.username\\some\\path;"; var expectedStacktrace = $"C:\\USER\\some\\path;\nC:\\test\\USER\\some\\path;\nC:\\no.username\\some\\path;"; var mockException = new Mock <System.Exception>(); mockException.Setup(exception => exception.StackTrace).Returns(stacktraceWithUserName); mockException.Setup(exception => exception.Message).Returns("Some error message"); // Mock method. HandledErrorLog actualLog = null; Mock.Get(_mockNetworkAdapter).Setup(adapter => adapter.SendAsync( It.IsAny <string>(), It.IsAny <string>(), It.IsAny <IDictionary <string, string> >(), It.IsAny <string>(), It.IsAny <CancellationToken>())) .Callback((string uri, string method, IDictionary <string, string> headers, string content, CancellationToken cancellation) => { actualLog = JsonConvert.DeserializeObject <LogContainer>(content, LogSerializer.SerializationSettings).Logs.Single() as HandledErrorLog; semaphore.Release(); }).ReturnsAsync(""); Crashes.TrackError(mockException.Object); // Wait until the http layer sends the log. semaphore.Wait(2000); Assert.IsNotNull(actualLog); Assert.AreEqual(expectedStacktrace, actualLog.Exception.StackTrace); }
public void TrackErrorWithValidParameters() { var semaphore = new SemaphoreSlim(0); HandledErrorLog actualLog = null; Mock.Get(_mockNetworkAdapter).Setup(adapter => adapter.SendAsync( It.IsAny <string>(), It.IsAny <string>(), It.IsAny <IDictionary <string, string> >(), It.IsAny <string>(), It.IsAny <CancellationToken>())) .Callback((string uri, string method, IDictionary <string, string> headers, string content, CancellationToken cancellation) => { actualLog = JsonConvert.DeserializeObject <LogContainer>(content, LogSerializer.SerializationSettings).Logs.Single() as HandledErrorLog; semaphore.Release(); }).ReturnsAsync(""); var exception = new System.Exception("Something went wrong."); var properties = new Dictionary <string, string> { { "k1", "v1" }, { "p2", "v2" } }; Crashes.TrackError(exception, properties); // Wait until the http layer sends the log. semaphore.Wait(2000); Assert.IsNotNull(actualLog); Assert.AreEqual(exception.Message, actualLog.Exception.Message); CollectionAssert.AreEquivalent(properties, actualLog.Properties as Dictionary <string, string>); }
public void TrackErrorWithUserId() { var semaphore = new SemaphoreSlim(0); var dummyUser = "******"; UserIdContext.Instance.UserId = dummyUser; HandledErrorLog actualLog = null; Mock.Get(_mockNetworkAdapter).Setup(adapter => adapter.SendAsync( It.IsAny <string>(), It.IsAny <string>(), It.IsAny <IDictionary <string, string> >(), It.IsAny <string>(), It.IsAny <CancellationToken>())) .Callback((string uri, string method, IDictionary <string, string> headers, string content, CancellationToken cancellation) => { actualLog = JsonConvert.DeserializeObject <LogContainer>(content, LogSerializer.SerializationSettings).Logs.Single() as HandledErrorLog; semaphore.Release(); }).ReturnsAsync(""); var exception = new System.Exception("Something went wrong."); Crashes.TrackError(exception); // Wait until the http layer sends the log. semaphore.Wait(2000); Assert.IsNotNull(actualLog); Assert.AreEqual(dummyUser, actualLog.UserId); }
public void TrackErrorWithTooManyProperties() { var semaphore = new SemaphoreSlim(0); HandledErrorLog actualLog = null; Mock.Get(_mockNetworkAdapter).Setup(adapter => adapter.SendAsync( It.IsAny <string>(), It.IsAny <string>(), It.IsAny <IDictionary <string, string> >(), It.IsAny <string>(), It.IsAny <CancellationToken>())) .Callback((string uri, string method, IDictionary <string, string> headers, string content, CancellationToken cancellation) => { actualLog = JsonConvert.DeserializeObject <LogContainer>(content, LogSerializer.SerializationSettings).Logs.Single() as HandledErrorLog; semaphore.Release(); }).ReturnsAsync(""); var exception = new System.Exception("Something went wrong."); var properties = new Dictionary <string, string>(); for (int i = 0; i < PropertyValidator.MaxProperties + 5; ++i) { properties[i.ToString()] = i.ToString(); } Crashes.TrackError(exception, properties); // Wait until the http layer sends the log. semaphore.Wait(2000); Assert.IsNotNull(actualLog); Assert.AreEqual(exception.Message, actualLog.Exception.Message); CollectionAssert.IsSubsetOf(actualLog.Properties as Dictionary <string, string>, properties); Assert.AreEqual(PropertyValidator.MaxProperties, actualLog.Properties.Count); }
public void LogError(Exception ex, MethodBase serviceMethodInfo, params object[] serviceParameterValues) { try { var innerMethodBase = (MethodBase)ex.Data[0]; var innerParameters = (string)ex.Data[1]; var stackTrace = (StackTrace)ex.Data[2]; int?lineNumber = null; if (stackTrace != null) { lineNumber = stackTrace.GetFrame(0)?.GetFileLineNumber(); } var serviceParameterNames = serviceMethodInfo.GetParameters(); var serviceParametersJs = SerializeParameters(serviceParameterNames, serviceParameterValues, serviceMethodInfo); if (ex.GetType() == typeof(BusinessException)) { var itExc = (BusinessException)ex; if (serviceMethodInfo.DeclaringType is { }) { var errorLog = new HandledErrorLog() { CreateDateTime = DateTime.Now, ErrorCode = itExc.Code, ErrorMessage = itExc.Message, ServiceName = serviceMethodInfo.DeclaringType.FullName, ServiceMethodName = serviceMethodInfo.Name, ServiceParameters = serviceParametersJs }; _repoContext.HandledErrorLogs.Add(errorLog); } _repoContext.SaveChanges(); }
public void TrackErrorWhenDisabled() { var logCount = 0; var semaphore = new SemaphoreSlim(0); HandledErrorLog actualLog = null; Mock.Get(_mockNetworkAdapter).Setup(adapter => adapter.SendAsync( It.IsAny <string>(), It.IsAny <string>(), It.IsAny <IDictionary <string, string> >(), It.IsAny <string>(), It.IsAny <CancellationToken>())) .Callback((string uri, string method, IDictionary <string, string> headers, string content, CancellationToken cancellation) => { actualLog = JsonConvert.DeserializeObject <LogContainer>(content, LogSerializer.SerializationSettings).Logs.Single() as HandledErrorLog; ++logCount; semaphore.Release(); }).ReturnsAsync(""); // If we disable the SDK. Crashes.SetEnabledAsync(false).Wait(); // When we track an error. var exception = new System.Exception("Something went wrong."); var properties = new Dictionary <string, string> { { "k1", "v1" }, { "p2", "v2" } }; Crashes.TrackError(exception, properties); // Then it's not sent. semaphore.Wait(2000); Assert.IsNull(actualLog); // If we re-enable. Crashes.SetEnabledAsync(true).Wait(); // When we track an error. Crashes.TrackError(exception, properties); // Then it's sent. semaphore.Wait(2000); Assert.IsNotNull(actualLog); Assert.AreEqual(1, logCount); Assert.AreEqual(exception.Message, actualLog.Exception.Message); Assert.IsNull(actualLog.Exception.StackTrace); CollectionAssert.AreEquivalent(properties, actualLog.Properties as Dictionary <string, string>); }
public void TrackErrorWithPropertiesAndAttachments() { var semaphore = new SemaphoreSlim(0); HandledErrorLog actualLog = null; ErrorAttachmentLog actualErrorAttachmentLog = null; Mock.Get(_mockNetworkAdapter).Setup(adapter => adapter.SendAsync( It.IsAny <string>(), It.IsAny <string>(), It.IsAny <IDictionary <string, string> >(), It.IsAny <string>(), It.IsAny <CancellationToken>())) .Callback((string uri, string method, IDictionary <string, string> headers, string content, CancellationToken cancellation) => { var log = JsonConvert.DeserializeObject <LogContainer>(content, LogSerializer.SerializationSettings).Logs[0]; if (log.GetType() == typeof(ErrorAttachmentLog)) { actualErrorAttachmentLog = log as ErrorAttachmentLog; } else { actualLog = log as HandledErrorLog; } if (actualLog != null && actualErrorAttachmentLog != null) { semaphore.Release(); } }).ReturnsAsync(""); var exception = new System.Exception("Something went wrong."); var properties = new Dictionary <string, string> { { "k1", "v1" }, { "p2", "v2" } }; var attachmentLog = GetValidErrorAttachmentLog(); Crashes.TrackError(exception, properties, attachmentLog); // Wait until the http layer sends the log. semaphore.Wait(2000); Assert.IsNotNull(actualLog); Assert.AreEqual(exception.Message, actualLog.Exception.Message); Assert.IsNotNull(actualErrorAttachmentLog); Assert.AreEqual(actualLog.Id, actualErrorAttachmentLog.ErrorId); CollectionAssert.AreEquivalent(attachmentLog.Data, actualErrorAttachmentLog.Data); CollectionAssert.AreEquivalent(properties, actualLog.Properties as Dictionary <string, string>); }
public void TrackErrorWithInvalidPropertiesAreSkipped() { var semaphore = new SemaphoreSlim(0); HandledErrorLog actualLog = null; Mock.Get(_mockNetworkAdapter).Setup(adapter => adapter.SendAsync( It.IsAny <string>(), It.IsAny <string>(), It.IsAny <IDictionary <string, string> >(), It.IsAny <string>(), It.IsAny <CancellationToken>())) .Callback((string uri, string method, IDictionary <string, string> headers, string content, CancellationToken cancellation) => { actualLog = JsonConvert.DeserializeObject <LogContainer>(content, LogSerializer.SerializationSettings).Logs.Single() as HandledErrorLog; semaphore.Release(); }).ReturnsAsync(""); var exception = new System.Exception("Something went wrong."); var properties = new Dictionary <string, string> { [""] = "testEmptyKeySkipped", ["testNullValueSkipped"] = null, [new string ('k', PropertyValidator.MaxPropertyKeyLength + 1)] = "testKeyTooLong", ["testValueTooLong"] = new string('v', PropertyValidator.MaxPropertyValueLength + 1), ["normalKey"] = "normalValue" }; Crashes.TrackError(exception, properties); // Wait until the http layer sends the log. semaphore.Wait(2000); Assert.IsNotNull(actualLog); Assert.AreEqual(exception.Message, actualLog.Exception.Message); // Check original dictionary not sent (copy is made). Assert.IsNotNull(actualLog.Properties); Assert.AreNotSame(properties, actualLog.Properties); // Check invalid values were skipped or truncated. Assert.AreEqual(3, actualLog.Properties.Count); Assert.AreEqual("normalValue", actualLog.Properties["normalKey"]); Assert.AreEqual("testKeyTooLong", actualLog.Properties[new string('k', PropertyValidator.MaxPropertyKeyLength)]); Assert.AreEqual(new string('v', PropertyValidator.MaxPropertyValueLength), actualLog.Properties["testValueTooLong"]); }