Bloom.NonFatalProblem.Report C# (CSharp) Method

Report() public static method

Always log, possibly inform the user, possibly throw the exception
public static Report ( ModalIf modalThreshold, PassiveIf passiveThreshold, string shortUserLevelMessage = null, string moreDetails = null, Exception exception = null ) : void
modalThreshold ModalIf Will show a modal dialog if the channel is this or lower
passiveThreshold PassiveIf Ignored for now
shortUserLevelMessage string Simple message that fits in small toast notification
moreDetails string Info adds information about the problem, which we get if they report the problem
exception System.Exception
return void
        public static void Report(ModalIf modalThreshold, PassiveIf passiveThreshold, string shortUserLevelMessage = null,
			string moreDetails = null,
			Exception exception = null)
        {
            // Simplify some checks below by tweaking the channel name on Linux.
            var channel = ApplicationUpdateSupport.ChannelName.ToLowerInvariant();
            if (channel.EndsWith("-unstable"))
                channel = channel.Replace("unstable", "alpha");
            try
            {
                shortUserLevelMessage = shortUserLevelMessage == null ? "" : shortUserLevelMessage;
                var fullDetailedMessage = shortUserLevelMessage;
                if(!string.IsNullOrEmpty(moreDetails))
                    fullDetailedMessage = fullDetailedMessage + System.Environment.NewLine + moreDetails;

                if(exception == null)
                {
                    //the code below is simpler if we always have an exception, even this thing that gives
                    //us the stacktrace we would otherwise be missing. Note, you might be tempted to throw
                    //and then catch an exception instead, but for some reason the resulting stack trace
                    //would contain only this method.
                    exception = new ApplicationException(new StackTrace().ToString());
                }

                if(Program.RunningUnitTests)
                {
                    //It's not clear to me what we can do that works for all unit test scenarios...
                    //We can imagine those for which throwing an exception at this point would be helpful,
                    //but there are others in which say, not finding a file is expected. Either way,
                    //the rest of the test should fail if the problem is real, so doing anything here
                    //would just be a help, not really necessary for getting the test to fail.
                    //So, for now I'm going to just go with doing nothing.
                    return;
                }

                //if this isn't going modal even for devs, it's just background noise and we don't want the
                //thousands of exceptions we were getting as with BL-3280
                if (modalThreshold != ModalIf.None)
                {
                    Analytics.ReportException(exception);
                }

                Logger.WriteError("NonFatalProblem: " + fullDetailedMessage, exception);

                if(Matches(modalThreshold).Any(s => channel.Contains(s)))
                {
                    try
                    {
                        SIL.Reporting.ErrorReport.ReportNonFatalExceptionWithMessage(exception, fullDetailedMessage);
                    }
                    catch(Exception)
                    {
                        //if we're running when the UI is already shut down, the above is going to throw.
                        //At least if we're running in a debugger, we'll stop here:
                        throw new ApplicationException(fullDetailedMessage + "Error trying to report normally.");
                    }
                    return;
                }

                //just convert from PassiveIf to ModalIf so that we don't have to duplicate code
                var passive = (ModalIf) ModalIf.Parse(typeof(ModalIf), passiveThreshold.ToString());
                if(!string.IsNullOrEmpty(shortUserLevelMessage) && Matches(passive).Any(s => channel.Contains(s)))
                {
                    ShowToast(shortUserLevelMessage, exception, fullDetailedMessage);
                }
            }
            catch(Exception errorWhileReporting)
            {
                // Don't annoy developers for expected error if the internet is not available.
                if (errorWhileReporting.Message.StartsWith("Bloom could not retrieve the URL") && Bloom.web.UrlLookup.FastInternetAvailable)
                {
                    Debug.Fail("error in nonfatalError reporting");
                }
                if (channel.Contains("alpha"))
                    ErrorReport.NotifyUserOfProblem(errorWhileReporting,"Error while reporting non fatal error");
            }
        }

Usage Example

        /// <summary>
        /// Will call either 'callback' or 'errorCallback' UNLESS the thumbnail is readonly, in which case it will do neither.
        /// </summary>
        /// <param name="book"></param>
        /// <param name="thumbnailOptions"></param>
        /// <param name="callback"></param>
        /// <param name="errorCallback"></param>
        private void RebuildThumbNail(Book.Book book, HtmlThumbNailer.ThumbnailOptions thumbnailOptions,
                                      Action <BookInfo, Image> callback, Action <BookInfo, Exception> errorCallback, bool async)
        {
            try
            {
                if (!book.Storage.RemoveBookThumbnail(thumbnailOptions.FileName))
                {
                    // thumbnail is marked readonly, so just use it
                    Image thumb;
                    book.Storage.TryGetPremadeThumbnail(thumbnailOptions.FileName, out thumb);
                    callback(book.BookInfo, thumb);
                    return;
                }

                _thumbnailProvider.RemoveFromCache(book.Storage.Key);

                thumbnailOptions.BorderStyle = GetThumbnailBorderStyle(book);
                GetThumbNailOfBookCover(book, thumbnailOptions, image => callback(book.BookInfo, image),
                                        error =>
                {
                    //Enhance; this isn't a very satisfying time to find out, because it's only going to happen if we happen to be rebuilding the thumbnail.
                    //It does help in the case where things are bad, so no thumbnail was created, but by then probably the user has already had some big error.
                    //On the other hand, given that they have this bad book in their collection now, it's good to just remind them that it's broken and not
                    //keep showing green error boxes.
                    book.CheckForErrors();
                    errorCallback(book.BookInfo, error);
                }, async);
            }
            catch (Exception error)
            {
                NonFatalProblem.Report(ModalIf.Alpha, PassiveIf.All, "Problem creating book thumbnail ", exception: error);
            }
        }
All Usage Examples Of Bloom.NonFatalProblem::Report