Ejemplo n.º 1
0
        /// <summary>
        /// Catch exceptions that are logged using NLog.
        /// </summary>
        /// <param name="configuration">this</param>
        /// <param name="minimumLevel">If specified, ignore all logged exceptions where the log level is less than the given one</param>
        public static void CatchNlogExceptions(this CoderrConfiguration configuration, LogLevel minimumLevel = null)
        {
            configuration.ContextProviders.Add(LogsProvider.Instance);

            if (LogManager.Configuration.AllTargets.Count == 0)
            {
                throw new InvalidOperationException("NLog have not yet been configured, which means that Coderr cannot catch log entries. Configure NLog first and then Coderr.");
            }

            //Target.Register<CoderrLogTarget>("Coderr");
            //            LogManager.Configuration.AddTarget("Coderr",new CoderrLogTarget());

            var target = new CoderrLogTarget();

            LogManager.Configuration.AddTarget("Coderr", target);

            if (minimumLevel != null && minimumLevel != LogLevel.Off)
            {
                LogManager.Configuration.AddRule(minimumLevel, LogLevel.Fatal, "Coderr");
            }
            else
            {
                LogManager.Configuration.AddRuleForAllLevels("Coderr");
            }
            LogManager.Configuration.Reload();

            LogManager.ConfigurationChanged += OnConfigChanged;
        }
Ejemplo n.º 2
0
        /// <summary>
        ///     Adds the codeRR logger to log4net.
        /// </summary>
        /// <param name="config">config</param>
        /// <exception cref="NotSupportedException">
        ///     This configuration/version of Log4Net do not allow dynamic adding of appenders.
        ///     Configure this adapter using code instead. See our online documentation for an example.
        /// </exception>
        public static void CatchLog4NetExceptions(this CoderrConfiguration config)
        {
            if (config == null)
            {
                throw new ArgumentNullException(nameof(config));
            }

            CatchLog4NetExceptions(config, Assembly.GetCallingAssembly());
        }
Ejemplo n.º 3
0
 public static void CatchWinFormsExeptions(this CoderrConfiguration configurator)
 {
     if (configurator == null)
     {
         throw new ArgumentNullException(nameof(configurator));
     }
     WinFormsErrorReporter.Activate();
     Err.Configuration.ContextProviders.Add(new OpenFormsCollector());
 }
Ejemplo n.º 4
0
 /// <summary>
 ///     Set a customized form which will be shown when OneTrueError detects an uncaught exception.
 /// </summary>
 /// <param name="configurator">OneTrueError configurator (accessed through <see cref="Err.Configuration" />)</param>
 /// <param name="formFactory">Factory used to create the form.</param>
 /// <example>
 ///     <para>Start by creating your custom form. It should contain something like this:</para>
 ///     <code>
 /// public partial class CustomReportDialog : Form
 /// {
 ///     public CustomReportDialog()
 ///     {
 ///         InitializeComponent();
 ///     }
 ///
 ///     // It's important that you store it
 ///     public string reportId { get; set; }
 ///
 ///     // And do something like this when the user clicks on the
 ///     // send report button
 ///     private void btnSubmit(object sender, EventArgs e)
 ///     {
 ///         var info = tbErrorDetails.Text;
 ///         var email = tbEmail.Text;
 ///
 ///         // supplied info, attach it.
 ///         if (!string.IsNullOrEmpty(info) || !string.IsNullOrEmpty(email))
 ///         {
 ///             OneTrue.SendReport(reportId, new UserSuppliedInformation(info, email));
 ///         }
 ///         else
 ///         {
 ///             // otherwise just send error and all contexts.
 ///             OneTrue.SendReport(reportId);
 ///         }
 ///     }
 ///
 ///     private void btnCancel_Click(object sender, EventArgs e)
 ///     {
 ///         Close();
 ///     }
 /// }
 /// </code>
 ///     <para>
 ///         Then configure OTE to use it:
 ///     </para>
 ///     <code>
 /// // don't forget to set the error reporter first.
 ///
 /// Err.Configuration.CatchWinFormsExceptions();
 /// Err.Configuration.SetErrorForm(context => new CustomReportDialog() { reportId = context.reportId });
 /// </code>
 /// </example>
 public static void SetErrorForm(this CoderrConfiguration configurator,
                                 Func <FormFactoryContext, Form> formFactory)
 {
     if (configurator == null)
     {
         throw new ArgumentNullException(nameof(configurator));
     }
     WinFormsErrorReporter.FormFactory = formFactory ?? throw new ArgumentNullException(nameof(formFactory));
 }
Ejemplo n.º 5
0
 /// <summary>
 ///     Take a screen shot of every form that is opened when an error happen.
 /// </summary>
 /// <param name="configurator">OneTrueError configurator (accessed through <see cref="Err.Configuration" />).</param>
 public static void TakeScreenshots(this CoderrConfiguration configurator)
 {
     if (configurator == null)
     {
         throw new ArgumentNullException(nameof(configurator));
     }
     WinFormsErrorReporter.Activate();
     Err.Configuration.ContextProviders.Add(new ScreenshotProvider(true));
 }
Ejemplo n.º 6
0
 public CoderrSerializationErrorHandler(CoderrConfiguration configuration, DuplicateDetector duplicateDetector)
 {
     if (configuration == null)
     {
         throw new ArgumentNullException(nameof(configuration));
     }
     _processor         = new ExceptionProcessor(configuration);
     _duplicateDetector = duplicateDetector;
 }
Ejemplo n.º 7
0
        /// <summary>
        /// Include log4net logs with every error report.
        /// </summary>
        /// <param name="config">instance</param>
        public static void AddLog4NetLogsToErrorReports(this CoderrConfiguration config)
        {
            if (_providerIsAdded)
            {
                return;
            }

            _providerIsAdded = true;
            Err.Configuration.ContextProviders.Add(LogsProvider.Instance);
        }
        public void using_credentials_config_should_add_our_own_uploaded_with_the_Specified_information()
        {
            var sut = new CoderrConfiguration();

            sut.Credentials(new Uri("http://localhost/abc"), "aaa", "bbb");
            var actual = (UploadToCoderr)sut.Uploaders.First();

            actual.ApiKey.Should().Be("aaa");
            actual.SharedSecret.Should().Be("bbb");
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Log entries to Coderr.
        /// </summary>
        /// <param name="sinkConfiguration">Serilog configuration.</param>
        /// <param name="configuration">Coderr configuration (typically <c>Err.Configuration</c>).</param>
        /// <param name="formatProvider">Optional log entry formatter.</param>
        /// <returns>Logger configuration object.</returns>
        public static LoggerConfiguration Coderr(
            this LoggerSinkConfiguration sinkConfiguration,
            CoderrConfiguration configuration = null,
            IFormatProvider formatProvider    = null)
        {
            var config = sinkConfiguration.Sink(new CoderrSink(formatProvider));

            (configuration ?? Err.Configuration).ContextProviders.Add(LogsProvider.Instance);
            return(config);
        }
Ejemplo n.º 10
0
        public void Credentials_should_add_the_default_uploader()
        {
            var dispatcher = Substitute.For <IUploadDispatcher>();

            var sut = new CoderrConfiguration(dispatcher);

            sut.Credentials(new Uri("http://localhost"), "ada", "buffen");

            dispatcher.Received().Register(Arg.Any <UploadToCoderr>());
        }
Ejemplo n.º 11
0
        public void should_add_context_data_object_to_report()
        {
            var dispatcher = Substitute.For <IUploadDispatcher>();
            var config     = new CoderrConfiguration(dispatcher);
            var ex         = new Exception("hello");

            var sut    = new ExceptionProcessor(config);
            var actual = sut.Build(ex, "Hello world");

            actual.GetCollectionProperty("ContextData", "Value").Should().Be("Hello world");
        }
Ejemplo n.º 12
0
        public void should_add_custom_collection_to_report()
        {
            var dispatcher = Substitute.For <IUploadDispatcher>();
            var config     = new CoderrConfiguration(dispatcher);
            var ex         = new Exception("hello");
            var collection = "Hello you too".ToContextCollection("MyName");

            var sut    = new ExceptionProcessor(config);
            var actual = sut.Build(ex, collection);

            actual.GetCollectionProperty("MyName", "Value").Should().Be("Hello you too");
        }
Ejemplo n.º 13
0
        public void should_upload_reports_if_there_are_no_filters()
        {
            var dispatcher = Substitute.For <IUploadDispatcher>();
            var config     = new CoderrConfiguration(dispatcher);
            var ex         = new Exception("hello");

            var sut = new ExceptionProcessor(config);

            sut.Process(ex);

            dispatcher.Received().Upload(Arg.Any <ErrorReportDTO>());
        }
        public void should_invoke_uploaders_when_a_new_report_is_being_uploaded()
        {
            var config   = new CoderrConfiguration();
            var uploader = Substitute.For <IReportUploader>();
            var report   = Substitute.For <ErrorReportDTO>();

            var sut = new UploadDispatcher(config);

            sut.Register(uploader);
            sut.Upload(report);

            uploader.Received().UploadReport(report);
        }
        public void should_invoke_uploaders_when_a_feedback_is_submitted()
        {
            var config   = new CoderrConfiguration();
            var uploader = Substitute.For <IReportUploader>();
            var feedback = Substitute.For <FeedbackDTO>();

            var sut = new UploadDispatcher(config);

            sut.Register(uploader);
            sut.Upload(feedback);

            uploader.Received().UploadFeedback(feedback);
        }
Ejemplo n.º 16
0
        public Reporter(Uri address, string appKey, string sharedSecret)
        {
            _config = new CoderrConfiguration();

            // Make sure that the collection exists so that other tests can use it.
            _config.ExceptionPreProcessor = context =>
                                            context.ContextCollections.GetCoderrCollection().Properties.Add("Hello", "Test");

            _config.EnvironmentName = "IntegrationTests";
            _uploader = new UploadToCoderr(address, appKey, sharedSecret);
            _config.Uploaders.Register(_uploader);
            _processor = new ExceptionProcessor(_config);
        }
Ejemplo n.º 17
0
        public void Should_be_able_to_build_a_report()
        {
            var upl    = new TestUploader();
            var config = new CoderrConfiguration();
            var filter = Substitute.For <IReportFilter>();

            config.Uploaders.Register(upl);
            config.FilterCollection.Add(filter);

            var processor = new ExceptionProcessor(config);
            var report    = processor.Build(new Exception());

            report.Should().NotBeNull();
        }
Ejemplo n.º 18
0
        public void Should_not_filter_BuildReport_as_nothing_is_sent_by_that_method()
        {
            var upl    = new TestUploader();
            var config = new CoderrConfiguration();
            var filter = Substitute.For <IReportFilter>();

            config.Uploaders.Register(upl);
            config.FilterCollection.Add(filter);
            filter.Invoke(Arg.Do((ReportFilterContext context) => context.CanSubmitReport = false));

            var processor = new ExceptionProcessor(config);
            var report    = processor.Build(new Exception());

            report.Should().NotBeNull();
        }
Ejemplo n.º 19
0
        public void should_add_log_entries_from_context()
        {
            var dispatcher = Substitute.For <IUploadDispatcher>();
            var config     = new CoderrConfiguration(dispatcher);
            var ex         = new Exception("hello");
            var context    = new ErrorReporterContext(this, ex)
            {
                LogEntries = new LogEntryDto[] { new LogEntryDto(DateTime.UtcNow, 1, "Hello") }
            };

            var sut    = new ExceptionProcessor(config);
            var actual = sut.Build(context);

            actual.LogEntries[0].Message.Should().Be(context.LogEntries[0].Message);
        }
Ejemplo n.º 20
0
        public void should_add_the_exception_to_the_report_so_that_it_can_be_uploaded()
        {
            var dispatcher = Substitute.For <IUploadDispatcher>();
            var config     = new CoderrConfiguration(dispatcher);
            var ex         = new Exception("hello");

            var sut     = new ExceptionProcessor(config);
            var actual1 = sut.Build(ex);
            var actual2 = sut.Build(ex, "Hello world");
            var actual3 = sut.Build(new ErrorReporterContext(this, ex));

            actual1.Exception.Message.Should().Be(ex.Message);
            actual2.Exception.Message.Should().Be(ex.Message);
            actual3.Exception.Message.Should().Be(ex.Message);
        }
Ejemplo n.º 21
0
        public void should_upload_reports_if_the_filters_says_ok()
        {
            var dispatcher = Substitute.For <IUploadDispatcher>();
            var config     = new CoderrConfiguration(dispatcher);
            var filter     = Substitute.For <IReportFilter>();
            var ex         = new Exception("hello");

            filter.Invoke(Arg.Do <ReportFilterContext>(context => context.CanSubmitReport = true));
            config.FilterCollection.Add(filter);

            var sut = new ExceptionProcessor(config);

            sut.Process(ex);

            dispatcher.Received().Upload(Arg.Any <ErrorReportDTO>());
        }
Ejemplo n.º 22
0
        public void Should_ignore_reports_that_have_already_been_reported_since_same_frameworks_have_multiple_injection_points_which_would_Report_the_same_exception()
        {
            var upl    = new TestUploader();
            var config = new CoderrConfiguration();

            config.Uploaders.Register(upl);
            var ex = new Exception("hello");

            ex.Data[ExceptionProcessor.AlreadyReportedSetting] = 1;

            var processor = new ExceptionProcessor(config);

            processor.Process(ex);

            upl.Report.Should().BeNull("because report should have been ignored");
        }
Ejemplo n.º 23
0
        public void Filter_should_not_affect_non_filtered_reports()
        {
            var upl    = new TestUploader();
            var config = new CoderrConfiguration();
            var filter = Substitute.For <IReportFilter>();

            config.Uploaders.Register(upl);
            config.FilterCollection.Add(filter);

            var processor = new ExceptionProcessor(config);

            processor.Process(new Exception());

            upl.Report.Should().NotBeNull("because the report is not affected by the filter");
            filter.ReceivedWithAnyArgs().Invoke(null);
        }
Ejemplo n.º 24
0
        public void should_use_the_assigned_reportId_factory_to_assign_a_report_id()
        {
            var dispatcher   = Substitute.For <IUploadDispatcher>();
            var config       = new CoderrConfiguration(dispatcher);
            var ex           = new Exception();
            var timesInvoked = 0;

            ReportIdGenerator.Assign(x => { timesInvoked++; return("a"); });

            var sut = new ExceptionProcessor(config);

            sut.Build(ex);
            sut.Build(ex, "Hello world");
            sut.Build(new ErrorReporterContext(this, ex));

            timesInvoked.Should().Be(3);
        }
Ejemplo n.º 25
0
        public void Should_be_able_to_filter_Reports()
        {
            var upl    = new TestUploader();
            var config = new CoderrConfiguration();
            var filter = Substitute.For <IReportFilter>();

            config.Uploaders.Register(upl);
            config.FilterCollection.Add(filter);
            filter.Invoke(Arg.Do((ReportFilterContext context) => context.CanSubmitReport = false));


            var processor = new ExceptionProcessor(config);

            processor.Process(new Exception());

            upl.Report.Should().BeNull("because report should have been filtered away");
        }
Ejemplo n.º 26
0
        public void Should_unpack_collections_that_are_attached_to_the_exception()
        {
            var upl    = new TestUploader();
            var config = new CoderrConfiguration();

            config.Uploaders.Register(upl);
            var json =
                @"{""$type"":""System.Collections.Generic.List`1[[Coderr.Client.Contracts.ContextCollectionDTO, Coderr.Client]], mscorlib"",""$values"":[{""Name"":""SqlCommand"",""Properties"":{""CommandText"":""WaitFor Delay '00:00:05'"",""CommandTimeout"":""3"",""ExecutionTime"":""00:00:03.0313327"",""OtherCommand[0]"":""select * from accounts where id=@id""}},{""Name"":""DbConnection"",""Properties"":{""ConnectionString"":""Data Source=.;Initial Catalog=OneTrueError;Integrated Security=True;Connect Timeout=30;multipleactiveresultsets=true"",""DataSource"":""."",""Database"":""OneTrueError"",""RunTime"":""00:00:03.0681702"",""State"":""Open"",""IsDisposed"":""False"",""ServerVersion"":""12.00.5207""}}]}";
            var ex = new InvalidOperationException();

            ex.Data["ErrCollections"] = json;

            var processor = new ExceptionProcessor(config);

            processor.Process(ex);

            upl.Report.ContextCollections.Should().Contain(x => x.Name == "SqlCommand");
        }
        public void Should_ignore_reports_that_have_already_been_reported_since_same_frameworks_have_multiple_injection_points_which_would_Report_the_same_exception()
        {
            var upl    = new TestUploader();
            var config = new CoderrConfiguration();
            var ex     = new Exception("hello");
            var ctx    = new ErrorReporterContext(this, ex);

            config.Uploaders.Register(upl);
            config.AddPartition(x =>
            {
                x.AddPartition("Id", "42");
            });

            var processor = new ExceptionProcessor(config);

            processor.Process(ctx);

            upl.Report.GetCollectionProperty("ErrPartitions", "Id").Should().Be("42");
        }
        public void Should_include_partitions_in_reports()
        {
            var upl    = new TestUploader();
            var config = new CoderrConfiguration();
            var ex     = new Exception("hello");
            var ctx    = new ErrorReporterContext(this, ex);

            config.Uploaders.Register(upl);
            config.AddPartition(x =>
            {
                x.AddPartition("Id", "42");
            });

            var processor = new ExceptionProcessor(config);

            processor.Process(ctx);

            upl.Report.GetCollectionProperty("CoderrData", "ErrPartition.Id").Should().Be("42");
        }
        /// <summary>
        ///     Adds the codeRR logger to log4net.
        /// </summary>
        /// <param name="config">config</param>
        /// <param name="assembly">Assembly that log4net was configured in (typically your entry assembly)</param>
        /// <exception cref="NotSupportedException">
        ///     This configuration/version of Log4Net do not allow dynamic adding of appenders.
        ///     Configure this adapter using code instead. See our online documentation for an example.
        /// </exception>
        public static void CatchLog4NetExceptions(this CoderrConfiguration config, Assembly assembly)
        {
            if (config == null)
            {
                throw new ArgumentNullException(nameof(config));
            }

            var root = ((Hierarchy)LogManager.GetRepository(assembly)).Root;

            if (!(root is IAppenderAttachable attachable))
            {
                throw new NotSupportedException(
                          "This configuration/version of Log4Net do not allow dynamic adding of appenders. Configure this adapter using code instead. See our online documentation for an example.");
            }

            var appender = new CoderrAppender();

            appender.ActivateOptions();
            attachable.AddAppender(appender);
        }
        /// <summary>
        ///     Activate our automatic detection of unhandled exceptions.
        /// </summary>
        /// <param name="configurator">configuration class</param>
        /// <remarks>
        ///     <para>Adds context collectors for forms, query string, sessions, user agent and http headers.</para>
        ///     <para>
        ///         MVC exceptions are detected through a custom global error filter.
        ///     </para>
        /// </remarks>
        public static void CatchMvcExceptions(this CoderrConfiguration configurator)
        {
            configurator.ContextProviders.Add(new FormProvider());
            configurator.ContextProviders.Add(new FileProvider());
            configurator.ContextProviders.Add(new QueryStringProvider());
            configurator.ContextProviders.Add(new SessionProvider());
            configurator.ContextProviders.Add(new HttpHeadersProvider());
            configurator.ContextProviders.Add(new HttpApplicationItemsProvider());

            configurator.ContextProviders.Add(new ViewDataProvider());
            configurator.ContextProviders.Add(new ViewBagProvider());
            configurator.ContextProviders.Add(new RouteDataProvider());
            configurator.ContextProviders.Add(new TempDataProvider());
            configurator.ContextProviders.Add(new ModelStateProvider());
            configurator.ContextProviders.Add(new ModelProvider());


            GlobalFilters.Filters.Add(new CoderrFilter());
            ErrorHttpModule.Activate();
        }