2026-04-16 15:21:24 +02:00
// Copyright (C) 2026, The Duplicati Team
2025-02-09 12:13:12 -03:00
// https://duplicati.com, hello@duplicati.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
2024-08-31 11:02:14 +02:00
// DEALINGS IN THE SOFTWARE.
2024-02-28 15:45:30 +01:00
2010-01-03 22:57:13 +00:00
using System ;
2025-02-09 12:13:12 -03:00
using System.Net.Http.Headers ;
2014-11-15 14:59:54 +01:00
using Duplicati.Library.Localization.Short ;
2009-09-23 16:42:45 +00:00
2010-06-19 21:08:21 +00:00
namespace Duplicati.Library.Interface
2009-09-23 16:42:45 +00:00
{
2017-01-09 10:32:38 +01:00
/// <summary>
2017-01-09 11:35:38 +01:00
/// A special exception that gives the user information on how to proceed.
2018-05-27 13:10:01 +02:00
/// Use this exception if the message is directed at the end user, and supplies
2017-01-09 11:35:38 +01:00
/// some guidance or explanation for the error. Exceptions of this type will
/// suppress the stack trace by default, on commandline output
2017-01-09 10:32:38 +01:00
/// </summary>
[Serializable]
public class UserInformationException : Exception
{
2018-03-12 14:07:11 +01:00
/// <summary>
/// The help ID for the exception
/// </summary>
public readonly string HelpID ;
public UserInformationException ( string message , string helpId )
2017-01-09 10:32:38 +01:00
: base ( message )
{
2018-03-12 14:07:11 +01:00
HelpID = helpId ;
2017-01-09 10:32:38 +01:00
}
2018-03-12 14:07:11 +01:00
public UserInformationException ( string message , string helpId , Exception innerException )
2017-01-09 10:32:38 +01:00
: base ( message , innerException )
{
2018-03-12 14:07:11 +01:00
HelpID = helpId ;
2017-01-09 10:32:38 +01:00
}
}
2009-09-23 16:42:45 +00:00
/// <summary>
/// An exception indicating that the requested folder is missing
/// </summary>
2011-03-12 10:03:54 +00:00
[Serializable]
2017-01-09 10:32:38 +01:00
public class FolderMissingException : UserInformationException
2009-09-23 16:42:45 +00:00
{
public FolderMissingException ()
2018-03-12 14:07:11 +01:00
: base ( Strings . Common . FolderMissingError , "FolderMissing" )
2009-09-23 16:42:45 +00:00
{ }
public FolderMissingException ( string message )
2018-03-12 14:07:11 +01:00
: base ( message , "FolderMissing" )
2009-09-23 16:42:45 +00:00
{ }
public FolderMissingException ( Exception innerException )
2018-03-12 14:07:11 +01:00
: base ( Strings . Common . FolderMissingError , "FolderMissing" , innerException )
2009-09-23 16:42:45 +00:00
{ }
public FolderMissingException ( string message , Exception innerException )
2018-03-12 14:07:11 +01:00
: base ( message , "FolderMissing" , innerException )
2009-09-23 16:42:45 +00:00
{ }
}
2014-11-15 14:59:54 +01:00
/// <summary>
/// An exception indicating that the requested folder is missing
/// </summary>
[Serializable]
2017-01-09 10:32:38 +01:00
public class FileMissingException : UserInformationException
2014-11-15 14:59:54 +01:00
{
public FileMissingException ()
2018-03-12 14:07:11 +01:00
: base ( LC . L ( "The requested file does not exist" ), "FileMissing" )
2014-11-15 14:59:54 +01:00
{ }
public FileMissingException ( string message )
2018-03-12 14:07:11 +01:00
: base ( message , "FileMissing" )
2014-11-15 14:59:54 +01:00
{ }
public FileMissingException ( Exception innerException )
2018-03-12 14:07:11 +01:00
: base ( LC . L ( "The requested file does not exist" ), "FileMissing" , innerException )
2014-11-15 14:59:54 +01:00
{ }
public FileMissingException ( string message , Exception innerException )
2018-03-12 14:07:11 +01:00
: base ( message , "FileMissing" , innerException )
2014-11-15 14:59:54 +01:00
{ }
}
2009-09-23 16:42:45 +00:00
/// <summary>
/// An exception indicating that the requested folder already existed
/// </summary>
2011-03-12 10:03:54 +00:00
[Serializable]
2017-01-09 10:32:38 +01:00
public class FolderAreadyExistedException : UserInformationException
2009-09-23 16:42:45 +00:00
{
2010-10-23 11:40:43 +00:00
public FolderAreadyExistedException ()
2018-03-12 14:07:11 +01:00
: base ( Strings . Common . FolderAlreadyExistsError , "FolderAlreadyExists" )
2009-09-23 16:42:45 +00:00
{ }
2010-10-23 11:40:43 +00:00
public FolderAreadyExistedException ( string message )
2018-03-12 14:07:11 +01:00
: base ( message , "FolderAlreadyExists" )
2009-09-23 16:42:45 +00:00
{ }
2010-10-23 11:40:43 +00:00
public FolderAreadyExistedException ( Exception innerException )
2018-03-12 14:07:11 +01:00
: base ( Strings . Common . FolderAlreadyExistsError , "FolderAlreadyExists" , innerException )
2009-09-23 16:42:45 +00:00
{ }
2010-10-23 11:40:43 +00:00
public FolderAreadyExistedException ( string message , Exception innerException )
2018-03-12 14:07:11 +01:00
: base ( message , "FolderAlreadyExists" , innerException )
2009-09-23 16:42:45 +00:00
{ }
}
2010-09-17 16:20:16 +00:00
/// <summary>
/// An exception indicating that the user has cancelled the action
/// </summary>
2011-03-12 10:03:54 +00:00
[Serializable]
2017-01-09 10:32:38 +01:00
public class CancelException : UserInformationException
2010-09-17 16:20:16 +00:00
{
public CancelException ()
2018-03-12 14:07:11 +01:00
: base ( Strings . Common . CancelExceptionError , "Cancelled" )
2010-09-17 16:20:16 +00:00
{ }
public CancelException ( string message )
2018-03-12 14:07:11 +01:00
: base ( message , "Cancelled" )
2010-09-17 16:20:16 +00:00
{ }
public CancelException ( Exception innerException )
2018-03-12 14:07:11 +01:00
: base ( Strings . Common . CancelExceptionError , "Cancelled" , innerException )
2010-09-17 16:20:16 +00:00
{ }
public CancelException ( string message , Exception innerException )
2018-03-12 14:07:11 +01:00
: base ( message , "Cancelled" , innerException )
2010-09-17 16:20:16 +00:00
{ }
2018-08-14 11:09:16 +02:00
}
/// <summary>
/// The reason why an operation is aborted
/// </summary>
public enum OperationAbortReason
{
/// <summary>
/// The operation is aborted, but this is considered a normal operation
/// </summary>
Normal ,
/// <summary>
/// The operation is aborted and this should give a warning
/// </summary>
Warning ,
/// <summary>
/// The operation is aborted and this is an error
/// </summary>
Error
}
/// <summary>
/// A class that signals the operation should be aborted
/// </summary>
[Serializable]
public class OperationAbortException : UserInformationException
{
/// <summary>
/// The reason for the abort operation
/// </summary>
public readonly OperationAbortReason AbortReason ;
public OperationAbortException ( OperationAbortReason reason , string message )
: base ( message , "OperationAborted" )
{
AbortReason = reason ;
}
public OperationAbortException ( OperationAbortReason reason , string message , Exception innerException )
: base ( message , "OperationAborted" , innerException )
{
AbortReason = reason ;
}
}
2021-05-18 21:28:23 -07:00
/// <summary>
/// An exception indicating that verification of uploaded volumes has failed
/// due to extra, missing, or duplicate files.
/// </summary>
[Serializable]
public class RemoteListVerificationException : UserInformationException
{
public RemoteListVerificationException ( string message , string helpId )
: base ( message , helpId )
2024-08-31 11:02:14 +02:00
{ }
2021-05-18 21:28:23 -07:00
public RemoteListVerificationException ( string message , string helpId , Exception innerException )
: base ( message , helpId , innerException )
2024-08-31 11:02:14 +02:00
{ }
2021-05-18 21:28:23 -07:00
}
2024-08-14 16:40:12 -03:00
/// <summary>
/// An exception indicating that the current encryption key does not match the key
/// used to encrypt the settings.
/// </summary>
[Serializable]
public class SettingsEncryptionKeyMismatchException : UserInformationException
{
public SettingsEncryptionKeyMismatchException ()
: base ( Strings . Common . SettingsKeyMismatchExceptionError , "SettingsKeyMismatch" )
2024-08-31 11:02:14 +02:00
{ }
2024-08-14 16:40:12 -03:00
}
2024-08-31 11:02:14 +02:00
/// <summary>
/// An exception indicating that the current encryption key does not match the key
/// used to encrypt the settings.
/// </summary>
[Serializable]
public class SettingsEncryptionKeyMissingException : UserInformationException
{
public SettingsEncryptionKeyMissingException ()
: base ( Strings . Common . SettingsKeyMissingExceptionError , "SettingsKeyMissing" )
{ }
}
2025-03-10 14:37:30 +01:00
2025-02-09 12:13:12 -03:00
/// <summary>
/// An exception for carrying the Retry-After header value on 429 Exceptions
/// </summary>
[Serializable]
public class TooManyRequestException ( RetryConditionHeaderValue retryAfter ) : Exception
{
public readonly RetryConditionHeaderValue RetryAfter = retryAfter ;
}
2025-03-10 14:37:30 +01:00
/// <summary>
/// An exception indicating that the database state is inconsistent
/// </summary>
[Serializable]
public class DatabaseInconsistencyException : UserInformationException
{
public DatabaseInconsistencyException ( string message )
: base ( message , "DatabaseInconsistency" )
{ }
public DatabaseInconsistencyException ( string message , string helpId )
: base ( message , helpId )
{ }
public DatabaseInconsistencyException ( string message , Exception innerException )
: base ( message , "DatabaseInconsistency" , innerException )
{ }
public DatabaseInconsistencyException ( string message , string helpId , Exception innerException )
: base ( message , helpId , innerException )
{ }
}
2025-05-21 17:19:27 +02:00
/// <summary>
/// Exception indicating that the test failed after the connection was established and authenticated
/// </summary>
[Serializable]
public class TestAfterConnectException : UserInformationException
{
public TestAfterConnectException ( string message , string helpId )
: base ( message , helpId )
{ }
public TestAfterConnectException ( string message , string helpId , Exception innerException )
: base ( message , helpId , innerException )
{ }
}
2026-07-11 12:11:30 +02:00
/// <summary>
/// Exception indicating that the backup database is currently locked by another running operation
/// and cannot be accessed concurrently.
/// </summary>
[Serializable]
public class DatabaseLockedException : UserInformationException
{
/// <summary>
/// The path to the database file that is locked.
/// </summary>
public readonly string DatabasePath ;
public DatabaseLockedException ( string databasePath )
: base ( LC . L ( $"The backup database is currently in use by another operation and cannot be accessed concurrently. Please wait for the running operation to finish and try again." ), "DatabaseLocked" )
{
DatabasePath = databasePath ;
}
public DatabaseLockedException ( string databasePath , Exception innerException )
: base ( LC . L ( $"The backup database is currently in use by another operation and cannot be accessed concurrently. Please wait for the running operation to finish and try again." ), "DatabaseLocked" , innerException )
{
DatabasePath = databasePath ;
}
public DatabaseLockedException ( string message , string helpId , Exception innerException )
: base ( message , helpId , innerException )
{
DatabasePath = string . Empty ;
}
}
2009-09-23 16:42:45 +00:00
}