Fixed: Improve Logging, Slowdown startup if non-recoverable errors

This commit is contained in:
Qstick 2020-01-19 16:04:16 -05:00
parent 01b0365884
commit f0ef6c3601
47 changed files with 197 additions and 77 deletions

View file

@ -95,11 +95,11 @@ private List<ReleaseResource> GetMovieReleases(int movieId)
} }
catch (NotImplementedException ex) catch (NotImplementedException ex)
{ {
_logger.Error(ex, "One or more indexer you selected does not support movie search yet: " + ex.Message); _logger.Error(ex, "One or more indexer you selected does not support movie search yet: {0}", ex.Message);
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.Error(ex, "Movie search failed: " + ex.Message); _logger.Error(ex, "Movie search failed: {0}", ex.Message);
} }
return new List<ReleaseResource>(); return new List<ReleaseResource>();

View file

@ -1,8 +1,9 @@
using System; using System;
using System.Security.AccessControl; using System.Security.AccessControl;
using System.Security.Principal; using System.Security.Principal;
using NLog; using NLog;
using NzbDrone.Common.Disk; using NzbDrone.Common.Disk;
using NzbDrone.Common.Exceptions;
using NzbDrone.Common.Instrumentation; using NzbDrone.Common.Instrumentation;
namespace NzbDrone.Common.EnvironmentInfo namespace NzbDrone.Common.EnvironmentInfo
@ -27,12 +28,24 @@ public AppFolderFactory(IAppFolderInfo appFolderInfo, IDiskProvider diskProvider
public void Register() public void Register()
{ {
_diskProvider.EnsureFolder(_appFolderInfo.AppDataFolder); try
{
_diskProvider.EnsureFolder(_appFolderInfo.AppDataFolder);
}
catch (UnauthorizedAccessException)
{
throw new RadarrStartupException("Cannot create AppFolder, Access to the path {0} is denied", _appFolderInfo.AppDataFolder);
}
if (OsInfo.IsWindows) if (OsInfo.IsWindows)
{ {
SetPermissions(); SetPermissions();
} }
if (!_diskProvider.FolderWritable(_appFolderInfo.AppDataFolder))
{
throw new RadarrStartupException("AppFolder {0} is not writable", _appFolderInfo.AppDataFolder);
}
} }
private void SetPermissions() private void SetPermissions()

View file

@ -0,0 +1,37 @@
using System;
namespace NzbDrone.Common.Exceptions
{
public class RadarrStartupException : NzbDroneException
{
public RadarrStartupException(string message, params object[] args)
: base("Radarr failed to start: " + string.Format(message, args))
{
}
public RadarrStartupException(string message)
: base("Radarr failed to start: " + message)
{
}
public RadarrStartupException()
: base("Radarr failed to start")
{
}
public RadarrStartupException(Exception innerException, string message, params object[] args)
: base("Radarr failed to start: " + string.Format(message, args), innerException)
{
}
public RadarrStartupException(Exception innerException, string message)
: base("Radarr failed to start: " + message, innerException)
{
}
public RadarrStartupException(Exception innerException)
: base("Radarr failed to start: " + innerException.Message)
{
}
}
}

View file

@ -19,7 +19,7 @@ private static void HandleTaskException(object sender, UnobservedTaskExceptionEv
var exception = e.Exception; var exception = e.Exception;
Console.WriteLine("Task Error: {0}", exception); Console.WriteLine("Task Error: {0}", exception);
Logger.Error(exception, "Task Error: " + exception.Message); Logger.Error(exception, "Task Error");
} }
private static void HandleAppDomainException(object sender, UnhandledExceptionEventArgs e) private static void HandleAppDomainException(object sender, UnhandledExceptionEventArgs e)
@ -48,7 +48,7 @@ private static void HandleAppDomainException(object sender, UnhandledExceptionEv
Console.WriteLine(exception.StackTrace); Console.WriteLine(exception.StackTrace);
Console.WriteLine("EPIC FAIL: {0}", exception); Console.WriteLine("EPIC FAIL: {0}", exception);
Logger.Fatal(exception, "EPIC FAIL: " + exception.Message); Logger.Fatal(exception, "EPIC FAIL.");
} }
} }
} }

View file

@ -69,7 +69,7 @@ private static void RegisterSentry(bool updateClient)
else else
{ {
dsn = RuntimeInfo.IsProduction dsn = RuntimeInfo.IsProduction
? "https://ef145e92efdd4155a0771c11c099695e@sentry.radarr.video/2" ? "https://a8e4c507c1f84578b55a841759a99dfb@sentry.radarr.video/2"
: "https://dee5b3fe26844368ac4458faa7d00a1f@sentry.radarr.video/9"; : "https://dee5b3fe26844368ac4458faa7d00a1f@sentry.radarr.video/9";
} }

View file

@ -14,6 +14,8 @@ public RadarrSentryPacket(string project, SentryEvent @event) :
{ {
DefaultValueHandling = DefaultValueHandling.Ignore DefaultValueHandling = DefaultValueHandling.Ignore
}; };
Breadcrumbs = @event.Breadcrumbs;
} }
public override string ToString(Formatting formatting) public override string ToString(Formatting formatting)

View file

@ -1,4 +1,7 @@
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using SharpRaven.Data;
using System;
using System.Linq;
namespace NzbDrone.Common.Instrumentation.Sentry namespace NzbDrone.Common.Instrumentation.Sentry
{ {
@ -22,6 +25,29 @@ public void CleansePacket(RadarrSentryPacket packet)
new CleansingJsonVisitor().Visit(target); new CleansingJsonVisitor().Visit(target);
packet.Extra = target; packet.Extra = target;
} }
if (packet.Breadcrumbs != null)
{
for (var i = 0; i < packet.Breadcrumbs.Count; i++)
{
packet.Breadcrumbs[i] = CleanseBreadcrumb(packet.Breadcrumbs[i]);
}
}
}
private static Breadcrumb CleanseBreadcrumb(Breadcrumb b)
{
try
{
var message = CleanseLogMessage.Cleanse(b.Message);
var data = b.Data?.ToDictionary(x => x.Key, y => CleanseLogMessage.Cleanse(y.Value));
return new Breadcrumb(b.Category) { Message = message, Type = b.Type, Data = data, Level = b.Level };
}
catch (Exception)
{
}
return b;
} }
} }
} }

View file

@ -76,6 +76,16 @@ public class SentryTarget : TargetWithLayout
{LogLevel.Warn, ErrorLevel.Warning}, {LogLevel.Warn, ErrorLevel.Warning},
}; };
private static readonly IDictionary<LogLevel, BreadcrumbLevel> BreadcrumbLevelMap = new Dictionary<LogLevel, BreadcrumbLevel>
{
{ LogLevel.Debug, BreadcrumbLevel.Debug },
{ LogLevel.Error, BreadcrumbLevel.Error },
{ LogLevel.Fatal, BreadcrumbLevel.Critical },
{ LogLevel.Info, BreadcrumbLevel.Info },
{ LogLevel.Trace, BreadcrumbLevel.Debug },
{ LogLevel.Warn, BreadcrumbLevel.Warning },
};
private readonly SentryDebounce _debounce; private readonly SentryDebounce _debounce;
private bool _unauthorized; private bool _unauthorized;
@ -199,6 +209,8 @@ protected override void Write(LogEventInfo logEvent)
try try
{ {
_client.AddTrail(new Breadcrumb(logEvent.LoggerName) { Level = BreadcrumbLevelMap[logEvent.Level], Message = logEvent.FormattedMessage });
// don't report non-critical events without exceptions // don't report non-critical events without exceptions
if (!IsSentryMessage(logEvent)) if (!IsSentryMessage(logEvent))
{ {
@ -249,12 +261,8 @@ protected override void Write(LogEventInfo logEvent)
Array.ForEach((string[])logEvent.Properties["Sentry"], sentryEvent.Fingerprint.Add); Array.ForEach((string[])logEvent.Properties["Sentry"], sentryEvent.Fingerprint.Add);
} }
var osName = Environment.GetEnvironmentVariable("OS_NAME");
var osVersion = Environment.GetEnvironmentVariable("OS_VERSION");
var runTimeVersion = Environment.GetEnvironmentVariable("RUNTIME_VERSION"); var runTimeVersion = Environment.GetEnvironmentVariable("RUNTIME_VERSION");
sentryEvent.Tags.Add("os_name", osName);
sentryEvent.Tags.Add("os_version", $"{osName} {osVersion}");
sentryEvent.Tags.Add("runtime_version", $"{PlatformInfo.PlatformName} {runTimeVersion}"); sentryEvent.Tags.Add("runtime_version", $"{PlatformInfo.PlatformName} {runTimeVersion}");
_client.Capture(sentryEvent); _client.Capture(sentryEvent);

View file

@ -103,6 +103,7 @@
<Compile Include="EnvironmentInfo\IOsVersionAdapter.cs" /> <Compile Include="EnvironmentInfo\IOsVersionAdapter.cs" />
<Compile Include="EnvironmentInfo\IPlatformInfo.cs" /> <Compile Include="EnvironmentInfo\IPlatformInfo.cs" />
<Compile Include="EnvironmentInfo\OsVersionModel.cs" /> <Compile Include="EnvironmentInfo\OsVersionModel.cs" />
<Compile Include="Exceptions\RadarrStartupException.cs" />
<Compile Include="Extensions\DictionaryExtensions.cs" /> <Compile Include="Extensions\DictionaryExtensions.cs" />
<Compile Include="Disk\GdiPlusInterop.cs" /> <Compile Include="Disk\GdiPlusInterop.cs" />
<Compile Include="Disk\OsPath.cs" /> <Compile Include="Disk\OsPath.cs" />

View file

@ -1,7 +1,8 @@
using System; using System;
using System.IO; using System.IO;
using NLog; using NLog;
using NzbDrone.Common.EnvironmentInfo; using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Common.Exceptions;
namespace NzbDrone.Common.Processes namespace NzbDrone.Common.Processes
{ {
@ -37,8 +38,8 @@ public void Write()
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.Error(ex, "Unable to write PID file: " + filename); _logger.Error(ex, "Unable to write PID file: {0}", filename);
throw; throw new RadarrStartupException(ex, "Unable to write PID file {0}", filename);
} }
} }
} }

View file

@ -2,6 +2,7 @@
using System.Net.Sockets; using System.Net.Sockets;
using NLog; using NLog;
using NzbDrone.Common.EnvironmentInfo; using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Common.Exceptions;
using NzbDrone.Common.Instrumentation; using NzbDrone.Common.Instrumentation;
using Radarr.Host; using Radarr.Host;
@ -15,7 +16,8 @@ private enum ExitCodes : int
{ {
Normal = 0, Normal = 0,
UnknownFailure = 1, UnknownFailure = 1,
RecoverableFailure = 2 RecoverableFailure = 2,
NonRecoverableFailure = 3
} }
public static void Main(string[] args) public static void Main(string[] args)
@ -34,6 +36,13 @@ public static void Main(string[] args)
} }
Bootstrap.Start(startupArgs, new ConsoleAlerts()); Bootstrap.Start(startupArgs, new ConsoleAlerts());
} }
catch (RadarrStartupException ex)
{
System.Console.WriteLine("");
System.Console.WriteLine("");
Logger.Fatal(ex, "EPIC FAIL!");
Exit(ExitCodes.NonRecoverableFailure);
}
catch (SocketException e) catch (SocketException e)
{ {
System.Console.WriteLine(""); System.Console.WriteLine("");
@ -53,7 +62,6 @@ public static void Main(string[] args)
Exit(ExitCodes.Normal); Exit(ExitCodes.Normal);
} }
private static void Exit(ExitCodes exitCode) private static void Exit(ExitCodes exitCode)
{ {
LogManager.Shutdown(); LogManager.Shutdown();
@ -64,6 +72,19 @@ private static void Exit(ExitCodes exitCode)
System.Threading.Thread.Sleep(1000); System.Threading.Thread.Sleep(1000);
if (exitCode == ExitCodes.NonRecoverableFailure)
{
System.Console.WriteLine("Non-recoverable failure, waiting for user intervention...");
for (int i = 0; i < 3600; i++)
{
System.Threading.Thread.Sleep(1000);
if (System.Console.KeyAvailable)
{
break;
}
}
}
// Please note that ReadLine silently succeeds if there is no console, KeyAvailable does not. // Please note that ReadLine silently succeeds if there is no console, KeyAvailable does not.
System.Console.ReadLine(); System.Console.ReadLine();
} }

View file

@ -1,9 +1,9 @@
using System; using System;
using NzbDrone.Common.Exceptions; using NzbDrone.Common.Exceptions;
namespace NzbDrone.Core.Datastore namespace NzbDrone.Core.Datastore
{ {
public class CorruptDatabaseException : NzbDroneException public class CorruptDatabaseException : RadarrStartupException
{ {
public CorruptDatabaseException(string message, params object[] args) : base(message, args) public CorruptDatabaseException(string message, params object[] args) : base(message, args)
{ {

View file

@ -1,4 +1,4 @@
using System; using System;
using System.Data.SQLite; using System.Data.SQLite;
using Marr.Data; using Marr.Data;
using Marr.Data.Reflection; using Marr.Data.Reflection;
@ -6,6 +6,7 @@
using NzbDrone.Common.Composition; using NzbDrone.Common.Composition;
using NzbDrone.Common.Disk; using NzbDrone.Common.Disk;
using NzbDrone.Common.EnvironmentInfo; using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Common.Exceptions;
using NzbDrone.Common.Instrumentation; using NzbDrone.Common.Instrumentation;
using NzbDrone.Core.Datastore.Migration.Framework; using NzbDrone.Core.Datastore.Migration.Framework;
@ -116,6 +117,10 @@ public IDatabase Create(MigrationContext migrationContext)
throw new CorruptDatabaseException("Database file: {0} is corrupt, restore from backup if available. See: https://github.com/Radarr/Radarr/wiki/FAQ#i-am-getting-an-error-database-disk-image-is-malformed", ex, fileName); throw new CorruptDatabaseException("Database file: {0} is corrupt, restore from backup if available. See: https://github.com/Radarr/Radarr/wiki/FAQ#i-am-getting-an-error-database-disk-image-is-malformed", ex, fileName);
} }
} }
catch (Exception e)
{
throw new RadarrStartupException(e, "Error creating main or log database");
}
var db = new Database(migrationContext.MigrationType.ToString(), () => var db = new Database(migrationContext.MigrationType.ToString(), () =>
{ {

View file

@ -206,7 +206,7 @@ private Rejection EvaluateSpec(IDecisionEngineSpecification spec, RemoteMovie re
{ {
e.Data.Add("report", remoteMovie.Release.ToJson()); e.Data.Add("report", remoteMovie.Release.ToJson());
e.Data.Add("parsed", remoteMovie.ParsedMovieInfo.ToJson()); e.Data.Add("parsed", remoteMovie.ParsedMovieInfo.ToJson());
_logger.Error(e, "Couldn't evaluate decision on " + remoteMovie.Release.Title + ", with spec: " + spec.GetType().Name); _logger.Error(e, "Couldn't evaluate decision on {0}, with spec: {1}", remoteMovie.Release.Title, spec.GetType().Name);
return new Rejection(string.Format("{0}: {1}", spec.GetType().Name, e.Message));//TODO UPDATE SPECS! return new Rejection(string.Format("{0}: {1}", spec.GetType().Name, e.Message));//TODO UPDATE SPECS!
} }

View file

@ -1,4 +1,4 @@
using System; using System;
using NLog; using NLog;
using NzbDrone.Common.Messaging; using NzbDrone.Common.Messaging;
using NzbDrone.Core.Configuration; using NzbDrone.Core.Configuration;
@ -74,8 +74,8 @@ private void RemoveFromDownloadClient(TrackedDownload trackedDownload)
} }
catch (Exception e) catch (Exception e)
{ {
_logger.Error(e, "Couldn't remove item from client " + trackedDownload.DownloadItem.Title); _logger.Error(e, "Couldn't remove item {0} from client {1}", trackedDownload.DownloadItem.Title, downloadClient.Name);
} }
} }
} }
} }

View file

@ -54,7 +54,7 @@ public void Clean()
} }
catch (Exception e) catch (Exception e)
{ {
_logger.Error(e, "Couldn't validate image " + image.RelativePath); _logger.Error(e, "Couldn't validate image {0}", image.RelativePath);
} }
} }
} }

View file

@ -1,4 +1,4 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using NLog; using NLog;
using NzbDrone.Core.Messaging.Commands; using NzbDrone.Core.Messaging.Commands;
@ -34,7 +34,7 @@ private void Clean()
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.Error(ex, "Error running housekeeping task: " + housekeeper.GetType().Name); _logger.Error(ex, "Error running housekeeping task: {0}", housekeeper.GetType().Name);
} }
} }

View file

@ -90,7 +90,7 @@ private List<DownloadDecision> Dispatch(Func<IIndexer, IEnumerable<ReleaseInfo>>
} }
catch (Exception e) catch (Exception e)
{ {
_logger.Error(e, "Error while searching for " + criteriaBase); _logger.Error(e, "Error while searching for {0}", criteriaBase);
} }
}).LogExceptions()); }).LogExceptions());
} }

View file

@ -244,11 +244,11 @@ protected virtual IList<ReleaseInfo> FetchReleases(IndexerPageableRequestChain p
var message = string.Format("{0} - {1}", ex.Message, url); var message = string.Format("{0} - {1}", ex.Message, url);
_logger.Warn(ex, message); _logger.Warn(ex, message);
} }
catch (Exception feedEx) catch (Exception ex)
{ {
_indexerStatusService.RecordFailure(Definition.Id); _indexerStatusService.RecordFailure(Definition.Id);
feedEx.Data.Add("FeedUrl", url); ex.Data.Add("FeedUrl", url);
_logger.Error(feedEx, "An error occurred while processing feed. " + url); _logger.Error(ex, "An error occurred while processing feed. {0}", url);
} }
return CleanupReleases(releases); return CleanupReleases(releases);

View file

@ -1,4 +1,4 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.IO; using System.IO;
@ -66,7 +66,7 @@ public virtual IList<ReleaseInfo> ParseResponse(IndexerResponse indexerResponse)
catch (Exception itemEx) catch (Exception itemEx)
{ {
itemEx.Data.Add("Item", item.Title()); itemEx.Data.Add("Item", item.Title());
_logger.Error(itemEx, "An error occurred while processing feed item from " + indexerResponse.Request.Url); _logger.Error(itemEx, "An error occurred while processing feed item from {0}", indexerResponse.Request.Url);
} }
} }

View file

@ -130,7 +130,7 @@ private void EnsureCovers(Movie movie, int retried = 0)
} }
catch (Exception e) catch (Exception e)
{ {
_logger.Error(e, "Couldn't download media cover for " + movie); _logger.Error(e, "Couldn't download media cover for {0}", movie);
} }
EnsureResizedCovers(movie, cover, !alreadyExists); EnsureResizedCovers(movie, cover, !alreadyExists);

View file

@ -224,7 +224,7 @@ private void CreateFolder(string directoryName)
} }
catch (IOException ex) catch (IOException ex)
{ {
_logger.Error(ex, "Unable to create directory: " + directoryName); _logger.Error(ex, "Unable to create directory: {0}", directoryName);
} }
_mediaFileAttributeService.SetFolderPermissions(directoryName); _mediaFileAttributeService.SetFolderPermissions(directoryName);

View file

@ -169,7 +169,7 @@ private ImportDecision GetDecision(string file, Movie movie, DownloadClientItem
} }
catch (Exception e) catch (Exception e)
{ {
_logger.Error(e, "Couldn't import file. " + file); _logger.Error(e, "Couldn't import file. {0}", file);
var localMovie = new LocalMovie { Path = file }; var localMovie = new LocalMovie { Path = file };
decision = new ImportDecision(localMovie, new Rejection("Unexpected error processing file")); decision = new ImportDecision(localMovie, new Rejection("Unexpected error processing file"));
@ -210,7 +210,7 @@ private Rejection EvaluateSpec(IImportDecisionEngineSpecification spec, LocalMov
{ {
//e.Data.Add("report", remoteEpisode.Report.ToJson()); //e.Data.Add("report", remoteEpisode.Report.ToJson());
//e.Data.Add("parsed", remoteEpisode.ParsedEpisodeInfo.ToJson()); //e.Data.Add("parsed", remoteEpisode.ParsedEpisodeInfo.ToJson());
_logger.Error(e, "Couldn't evaluate decision on " + localMovie.Path); _logger.Error(e, "Couldn't evaluate decision on {0}", localMovie.Path);
return new Rejection(string.Format("{0}: {1}", spec.GetType().Name, e.Message)); return new Rejection(string.Format("{0}: {1}", spec.GetType().Name, e.Message));
} }

View file

@ -55,11 +55,11 @@ public Decision IsSatisfiedBy(LocalMovie localMovie, DownloadClientItem download
} }
catch (DirectoryNotFoundException ex) catch (DirectoryNotFoundException ex)
{ {
_logger.Error("Unable to check free disk space while importing. " + ex.Message); _logger.Error(ex, "Unable to check free disk space while importing.");
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.Error(ex, "Unable to check free disk space while importing: " + localMovie.Path); _logger.Error(ex, "Unable to check free disk space while importing: {0}", localMovie.Path);
} }
return Decision.Accept(); return Decision.Accept();

View file

@ -126,7 +126,7 @@ private void RenameFiles(List<MovieFile> movieFiles, Movie movie, string oldMovi
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.Error(ex, "Failed to rename file: " + oldMovieFilePath); _logger.Error(ex, "Failed to rename file: {0}", oldMovieFilePath);
} }
} }

View file

@ -44,18 +44,18 @@ private void ExecuteCommands()
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.Error(ex, "Error occurred while executing task " + command.Name); _logger.Error(ex, "Error occurred while executing task {0}", command.Name);
} }
} }
} }
catch (ThreadAbortException ex) catch (ThreadAbortException ex)
{ {
_logger.Error(ex, "Thread aborted: " + ex.Message); _logger.Error(ex, "Thread aborted");
Thread.ResetAbort(); Thread.ResetAbort();
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.Error(ex, "Unknown error in thread: " + ex.Message); _logger.Error(ex, "Unknown error in thread");
} }
} }

View file

@ -180,7 +180,7 @@ public void Execute(RefreshMovieCommand message)
} }
catch (Exception e) catch (Exception e)
{ {
_logger.Error(e, "Couldn't refresh info for {0}".Inject(movie)); _logger.Error(e, "Couldn't refresh info for {0}", movie);
} }
} }
@ -194,7 +194,7 @@ public void Execute(RefreshMovieCommand message)
} }
catch (Exception e) catch (Exception e)
{ {
_logger.Error(e, "Couldn't rescan movie {0}".Inject(movie)); _logger.Error(e, "Couldn't rescan movie {0}", movie);
} }
} }
} }

View file

@ -102,7 +102,7 @@ protected virtual NetImportFetchResult FetchMovies(NetImportPageableRequestChain
{ {
anyFailure = true; anyFailure = true;
feedEx.Data.Add("FeedUrl", url); feedEx.Data.Add("FeedUrl", url);
_logger.Error(feedEx, "An error occurred while processing feed. " + url); _logger.Error(feedEx, "An error occurred while processing feed. {0}", url);
} }
return new NetImportFetchResult {Movies = movies, AnyFailure = anyFailure}; return new NetImportFetchResult {Movies = movies, AnyFailure = anyFailure};

View file

@ -54,7 +54,7 @@ public virtual IList<Movie> ParseResponse(NetImportResponse importResponse)
catch (Exception itemEx) catch (Exception itemEx)
{ {
//itemEx.Data.Add("Item", item.Title()); //itemEx.Data.Add("Item", item.Title());
_logger.Error(itemEx, "An error occurred while processing feed item from " + importResponse.Request.Url); _logger.Error(itemEx, "An error occurred while processing feed item from {0}", importResponse.Request.Url);
} }
} }

View file

@ -52,16 +52,16 @@ public ValidationFailure Test(BoxcarSettings settings)
{ {
if (ex.Response.StatusCode == HttpStatusCode.Unauthorized) if (ex.Response.StatusCode == HttpStatusCode.Unauthorized)
{ {
_logger.Error(ex, "Access Token is invalid: " + ex.Message); _logger.Error(ex, "Access Token is invalid: {0}", ex.Message);
return new ValidationFailure("Token", "Access Token is invalid"); return new ValidationFailure("Token", "Access Token is invalid");
} }
_logger.Error(ex, "Unable to send test message: " + ex.Message); _logger.Error(ex, "Unable to send test message: {0}", ex.Message);
return new ValidationFailure("Token", "Unable to send test message"); return new ValidationFailure("Token", "Unable to send test message");
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.Error(ex, "Unable to send test message: " + ex.Message); _logger.Error(ex, "Unable to send test message: {0}", ex.Message);
return new ValidationFailure("", "Unable to send test message"); return new ValidationFailure("", "Unable to send test message");
} }
} }
@ -84,7 +84,7 @@ private void SendNotification(string title, string message, RestRequest request,
{ {
if (ex.Response.StatusCode == HttpStatusCode.Unauthorized) if (ex.Response.StatusCode == HttpStatusCode.Unauthorized)
{ {
_logger.Error(ex, "Access Token is invalid: " + ex.Message); _logger.Error(ex, "Access Token is invalid: {0}", ex.Message);
throw; throw;
} }

View file

@ -68,7 +68,7 @@ public ValidationFailure Test(EmailSettings settings)
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.Error(ex, "Unable to send test email: " + ex.Message); _logger.Error(ex, "Unable to send test email: {0}", ex.Message);
return new ValidationFailure("Server", "Unable to send test email"); return new ValidationFailure("Server", "Unable to send test email");
} }

View file

@ -151,7 +151,7 @@ public ValidationFailure Test(GrowlSettings settings)
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.Error(ex, "Unable to send test message: " + ex.Message); _logger.Error(ex, "Unable to send test message: {0}", ex.Message);
return new ValidationFailure("Host", "Unable to send test message"); return new ValidationFailure("Host", "Unable to send test message");
} }

View file

@ -53,7 +53,7 @@ public ValidationFailure Test(MediaBrowserSettings settings)
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.Error(ex, "Unable to send test message: " + ex.Message); _logger.Error(ex, "Unable to send test message: {0}", ex.Message);
return new ValidationFailure("Host", "Unable to send test message: " + ex.Message); return new ValidationFailure("Host", "Unable to send test message: " + ex.Message);
} }

View file

@ -87,7 +87,7 @@ public void Handle(MovieGrabbedEvent message)
catch (Exception ex) catch (Exception ex)
{ {
_logger.Error(ex, "Unable to send OnGrab notification to: " + notification.Definition.Name); _logger.Error(ex, "Unable to send OnGrab notification to: {0}", notification.Definition.Name);
} }
} }
} }

View file

@ -75,7 +75,7 @@ public ValidationFailure Test(NotifyMyAndroidSettings settings)
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.Error(ex, "Unable to send test message: " + ex.Message); _logger.Error(ex, "Unable to send test message: {0}", ex.Message);
return new ValidationFailure("ApiKey", "Unable to send test message"); return new ValidationFailure("ApiKey", "Unable to send test message");
} }

View file

@ -63,7 +63,7 @@ public ValidationFailure Test(PlexClientSettings settings)
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.Error(ex, "Unable to send test message: " + ex.Message); _logger.Error(ex, "Unable to send test message: {0}", ex.Message);
return new ValidationFailure("Host", "Unable to send test message"); return new ValidationFailure("Host", "Unable to send test message");
} }

View file

@ -175,12 +175,12 @@ public ValidationFailure Test(PlexServerSettings settings)
} }
catch(PlexAuthenticationException ex) catch(PlexAuthenticationException ex)
{ {
_logger.Error(ex, "Unable to connect to Plex Server: " + ex.Message); _logger.Error(ex, "Unable to connect to Plex Server: {0}", ex.Message);
return new ValidationFailure("Username", "Incorrect username or password"); return new ValidationFailure("Username", "Incorrect username or password");
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.Error(ex, "Unable to connect to Plex Server: " + ex.Message); _logger.Error(ex, "Unable to connect to Plex Server: {0}", ex.Message);
return new ValidationFailure("Host", "Unable to connect to Plex Server"); return new ValidationFailure("Host", "Unable to connect to Plex Server");
} }

View file

@ -94,7 +94,7 @@ public ValidationFailure Test(ProwlSettings settings)
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.Error(ex, "Unable to send test message: " + ex.Message); _logger.Error(ex, "Unable to send test message: {0}", ex.Message);
return new ValidationFailure("ApiKey", "Unable to send test message"); return new ValidationFailure("ApiKey", "Unable to send test message");
} }

View file

@ -42,7 +42,7 @@ public void SendNotification(string title, string message, PushBulletSettings se
} }
catch (PushBulletException ex) catch (PushBulletException ex)
{ {
_logger.Error(ex, "Unable to send test message to: " + channelTag); _logger.Error(ex, "Unable to send test message to: {0}", channelTag);
error = true; error = true;
} }
} }
@ -61,7 +61,7 @@ public void SendNotification(string title, string message, PushBulletSettings se
} }
catch (PushBulletException ex) catch (PushBulletException ex)
{ {
_logger.Error(ex, "Unable to send test message to: " + deviceId); _logger.Error(ex, "Unable to send test message to: {0}", deviceId);
error = true; error = true;
} }
} }
@ -101,16 +101,16 @@ public ValidationFailure Test(PushBulletSettings settings)
{ {
if (ex.Response.StatusCode == HttpStatusCode.Unauthorized) if (ex.Response.StatusCode == HttpStatusCode.Unauthorized)
{ {
_logger.Error(ex, "API Key is invalid: " + ex.Message); _logger.Error(ex, "API Key is invalid: {0}", ex.Message);
return new ValidationFailure("ApiKey", "API Key is invalid"); return new ValidationFailure("ApiKey", "API Key is invalid");
} }
_logger.Error(ex, "Unable to send test message: " + ex.Message); _logger.Error(ex, "Unable to send test message: {0}", ex.Message);
return new ValidationFailure("ApiKey", "Unable to send test message"); return new ValidationFailure("ApiKey", "Unable to send test message");
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.Error(ex, "Unable to send test message: " + ex.Message); _logger.Error(ex, "Unable to send test message: {0}", ex.Message);
return new ValidationFailure("", "Unable to send test message"); return new ValidationFailure("", "Unable to send test message");
} }
@ -165,7 +165,7 @@ private void SendNotification(string title, string message, RestRequest request,
{ {
if (ex.Response.StatusCode == HttpStatusCode.Unauthorized) if (ex.Response.StatusCode == HttpStatusCode.Unauthorized)
{ {
_logger.Error(ex, "API Key is invalid: " + ex.Message); _logger.Error(ex, "API Key is invalid: {0}", ex.Message);
throw; throw;
} }

View file

@ -73,30 +73,30 @@ public ValidationFailure Test(PushalotSettings settings)
{ {
if (ex.Response.StatusCode == HttpStatusCode.Unauthorized) if (ex.Response.StatusCode == HttpStatusCode.Unauthorized)
{ {
_logger.Error(ex, "Authentication Token is invalid: " + ex.Message); _logger.Error(ex, "Authentication Token is invalid: {0}", ex.Message);
return new ValidationFailure("AuthToken", "Authentication Token is invalid"); return new ValidationFailure("AuthToken", "Authentication Token is invalid");
} }
if (ex.Response.StatusCode == HttpStatusCode.NotAcceptable) if (ex.Response.StatusCode == HttpStatusCode.NotAcceptable)
{ {
_logger.Error(ex, "Message limit reached: " + ex.Message); _logger.Error(ex, "Message limit reached: {0}", ex.Message);
return new ValidationFailure("AuthToken", "Message limit reached"); return new ValidationFailure("AuthToken", "Message limit reached");
} }
if (ex.Response.StatusCode == HttpStatusCode.Gone) if (ex.Response.StatusCode == HttpStatusCode.Gone)
{ {
_logger.Error(ex, "Authorization Token is no longer valid: " + ex.Message); _logger.Error(ex, "Authorization Token is no longer valid: {0}", ex.Message);
return new ValidationFailure("AuthToken", "Authorization Token is no longer valid, please use a new one."); return new ValidationFailure("AuthToken", "Authorization Token is no longer valid, please use a new one.");
} }
var response = Json.Deserialize<PushalotResponse>(ex.Response.Content); var response = Json.Deserialize<PushalotResponse>(ex.Response.Content);
_logger.Error(ex, "Unable to send test message: " + ex.Message); _logger.Error(ex, "Unable to send test message: {0}", ex.Message);
return new ValidationFailure("AuthToken", response.Description); return new ValidationFailure("AuthToken", response.Description);
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.Error(ex, "Unable to send test message: " + ex.Message); _logger.Error(ex, "Unable to send test message: {0}", ex.Message);
return new ValidationFailure("", "Unable to send test message"); return new ValidationFailure("", "Unable to send test message");
} }

View file

@ -59,7 +59,7 @@ public ValidationFailure Test(PushoverSettings settings)
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.Error(ex, "Unable to send test message: " + ex.Message); _logger.Error(ex, "Unable to send test message: {0}", ex.Message);
return new ValidationFailure("ApiKey", "Unable to send test message"); return new ValidationFailure("ApiKey", "Unable to send test message");
} }

View file

@ -51,7 +51,7 @@ public ValidationFailure Test(TelegramSettings settings)
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.Error(ex, "Unable to send test message: " + ex.Message); _logger.Error(ex, "Unable to send test message: {0}", ex.Message);
var restException = ex as RestException; var restException = ex as RestException;

View file

@ -131,7 +131,7 @@ public ValidationFailure Test(TwitterSettings settings)
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.Error(ex, "Unable to send test message: " + ex.Message); _logger.Error(ex, "Unable to send test message: {0}", ex.Message);
return new ValidationFailure("Host", "Unable to send test message"); return new ValidationFailure("Host", "Unable to send test message");
} }
return null; return null;

View file

@ -63,7 +63,7 @@ private XbmcVersion GetJsonVersion(XbmcSettings settings)
{ {
var response = _proxy.GetJsonVersion(settings); var response = _proxy.GetJsonVersion(settings);
_logger.Debug("Getting version from response: " + response); _logger.Debug("Getting version from response: {0}", response);
var result = Json.Deserialize<XbmcJsonResult<JObject>>(response); var result = Json.Deserialize<XbmcJsonResult<JObject>>(response);
var versionObject = result.Result.Property("version"); var versionObject = result.Result.Property("version");
@ -115,7 +115,7 @@ public ValidationFailure Test(XbmcSettings settings, string message)
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.Error(ex, "Unable to send test message: " + ex.Message); _logger.Error(ex, "Unable to send test message: {0}", ex.Message);
return new ValidationFailure("Host", "Unable to send test message"); return new ValidationFailure("Host", "Unable to send test message");
} }

View file

@ -253,7 +253,7 @@ public static ParsedMovieInfo ParseMovieTitle(string title, bool isLenient, bool
catch (Exception e) catch (Exception e)
{ {
if (!title.ToLower().Contains("password") && !title.ToLower().Contains("yenc")) if (!title.ToLower().Contains("password") && !title.ToLower().Contains("yenc"))
Logger.Error(e, "An error has occurred while trying to parse " + title); Logger.Error(e, "An error has occurred while trying to parse {0}", title);
} }
Logger.Debug("Unable to parse {0}", title); Logger.Debug("Unable to parse {0}", title);

View file

@ -4,9 +4,11 @@
using NLog; using NLog;
using NzbDrone.Common.Composition; using NzbDrone.Common.Composition;
using NzbDrone.Common.EnvironmentInfo; using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Common.Exceptions;
using NzbDrone.Common.Instrumentation; using NzbDrone.Common.Instrumentation;
using NzbDrone.Common.Processes; using NzbDrone.Common.Processes;
using NzbDrone.Common.Security; using NzbDrone.Common.Security;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.Instrumentation; using NzbDrone.Core.Instrumentation;
namespace Radarr.Host namespace Radarr.Host
@ -49,6 +51,10 @@ public static void Start(StartupContext startupContext, IUserAlert userAlert, Ac
SpinToExit(appMode); SpinToExit(appMode);
} }
} }
catch (InvalidConfigFileException ex)
{
throw new RadarrStartupException(ex);
}
catch (TerminateApplicationException e) catch (TerminateApplicationException e)
{ {
Logger.Info(e.Message); Logger.Info(e.Message);

View file

@ -43,7 +43,7 @@ public void LaunchWebUI()
} }
catch (Exception e) catch (Exception e)
{ {
_logger.Error(e, "Couldn't open default browser to " + url); _logger.Error(e, "Couldn't open default browser to {0}", url);
} }
} }
} }