I am trying to catch the Access Denied Exception when trying to upload a file via FTP using FluentFTP
try
{
client = new FtpClient(serverName, userName, password);
client.AutoConnect();
client.RetryAttempts = 3;
client.UploadFile(localPath, serverPath, FtpRemoteExists.Overwrite, false,FtpVerify.Retry);
}
catch (Exception ex)
{
if (ex is FtpException && ex.InnerException?.Message == "Access is denied. ")
{
//Do something here
throw ex;
}
throw;
}
I cannot rely on "Access is denied. " on this string but I don't know how to catch that Exception.
I would recommend that you check the directory before moving on to upload:
if (!client.DirectoryExists(serverPath))
{
//do somthing...
}
you can also try to get the permission of file/directory and catch exception thrown by it:
try
{
...
var ftpListItem = client.GetFilePermissions(pathOnTheServer);
if (ftpListItem.GroupPermissions == FtpPermission.None ||
ftpListItem.OthersPermissions == FtpPermission.None
) //or other permission category..
{
//do something...
return;
}
//do other things..
}
catch (FtpCommandException ex) //get permission failed
{
//handle exception
}
catch(Exception ex)
{
//hendel other exceptions
}
Bounce:
you can use using statement to properly dispose the client after done using it:
using (var client = new FtpClient(serverName, userName, password))
{
//your code...
}
Related
The best way to explain my question is with the following pseudo-code:
try
{
//Do work
}
catch (SqlException ex)
{
if (ex.Number == -2)
{
debugLogSQLTimeout(ex);
}
else
{
//How to go to 'Exception' handler?
}
}
catch (Exception ex)
{
debugLogGeneralException(ex);
}
Exception ex = null;
try
{
//Do work
}
catch (SqlException sqlEx)
{
ex = sqlEx;
if (ex.Number == -2)
{
//..
}
else
{
//..
}
}
catch (Exception generalEx)
{
ex = generalEx;
}
finally()
{
if (ex != null) debugLogGeneralException(ex);
}
The first catch clause that matches is the only one that can possibly run on the same try block.
The best way I can think of to do what you're attempting is to include casts and conditionals in the more general type:
try
{
//Do work
}
catch (Exception ex)
{
var sqlEx = ex as SqlException;
if (sqlEx != null && sqlEx.Number == -2)
{
debugLogSQLTimeout(ex);
}
else
{
debugLogGeneralException(ex);
}
}
If you find yourself writing this over and over again throughout your data layer, at least take the time to encapsulate it in a method.
I do not believe there is any way to do this as the catch blocks are in different scopes. There's no way to re-throw without exiting the try block and no way to 'call' the final catch block because it's only triggered during an exception.
I would suggest the same as roman m above and just make the same call. Otherwise you have to do something really bad. Like the below crazy code which you should never ever use but i included because it does something like what you want.
In general I think what you are doing is controlling normal flow via exceptions which isn't recommended. If you are trying to track for timeouts, you should probably just handle that another way.
Note that you could do something like the code below with the insanity of a goto statement, but i included it so no one can forget what a bad idea this is. =)
void Main()
{
Madness(new NotImplementedException("1")); //our 'special' case we handle
Madness(new NotImplementedException("2")); //our 'special' case we don't handle
Madness(new Exception("2")); //some other error
}
void Madness(Exception e){
Exception myGlobalError;
try
{
throw e;
}
catch (NotImplementedException ex)
{
if (ex.Message.Equals("1"))
{
Console.WriteLine("handle special error");
}
else
{
myGlobalError = ex;
Console.WriteLine("going to our crazy handler");
goto badidea;
}
}
catch (Exception ex)
{
myGlobalError = ex;
Console.WriteLine("going to our crazy handler");
goto badidea;
}
return;
badidea:
try{
throw myGlobalError;
}
catch (Exception ex)
{
Console.WriteLine("this is crazy!");
}
}
// Define other methods and classes here
I'm trying to catch a duplicate key violation. I can see the System.OleDB.OleDBException in the Intellisense pop up, but the inner exception is null. How do I access the Error Code in the System.OleDB.OleDBException?
Greg
try
{
MyData.ConExec(sSQL);
}
catch (Exception ex)
{
OleDbException innerException = ex.InnerException as OleDbException;
if (innerException.ErrorCode == -2147217873)
{
// handle exception here..
}
else
{
throw;
}
}
don't declare an instance of the exception. It will surely return empty if you do.
try
{
MyData.ConExec(sSQL);
}
catch (OleDbException ex)
{
// handle excpetion here...
if (ex.ErrorCode == -2147217873)
{
}
}
catch (Exception e)
{
// if other exception will occur
}
In my method that writes to a database, I handle errors as shown in the code below. In catch (DbUpdateException ex) I want to re-throw the exception and catch it in the last catch (Exception ex).
Is that possible and how to do that? Code below doesn't do that.
using (Entities context = new Entities())
{
try
{
context.Office.Add(office);
retVal = context.SaveChanges();
}
catch (DbUpdateException ex)
{
SqlException innerException = ex.GetBaseException() as SqlException;
if (innerException != null && innerException.Number == (int)SQLErrorCode.DUPLICATE_UNIQUE_CONSTRAINT)
{
throw
new Exception("Error ocurred");
}
//This is momenty where exception is thrown.
else
{
throw ex;
}
}
catch (Exception ex)
{
throw
new Exception("Error");
}
}
The following would be better:
context.Office.Add(office);
retVal = context.SaveChanges();
Let the except bubble up. No need to catch stuff if all you are going to do is re-throw.
Note: throw ex; will reset the stack trace - you want to do throw; normally.
If you want to catch exceptions from other catches then they cannot be on the same level.
Your current code has this structure:
try
{
}
catch (...)
{
}
catch (...)
{
}
You need to change it to:
try
{
try
{
}
catch (...)
{
// throw X
}
}
catch (...)
{
// catch X here
}
But you should think very carefully if you really want/need this. It does not look like a productive error handling pattern.
And see this answer for the 4 different ways to (re)throw an exception and their consequences.
have you tried try nesting your try...catch blocks?
using (Entities context = new Entities())
{
try
{
try
{
context.Office.Add(office);
retVal = context.SaveChanges();
}
catch (DbUpdateException ex)
{
SqlException innerException = ex.GetBaseException() as SqlException;
if (innerException != null && innerException.Number == (int)SQLErrorCode.DUPLICATE_UNIQUE_CONSTRAINT)
{
throw new Exception("Error ocurred");
}
//This is momenty where exception is thrown.
else
{
throw ex;
}
}
}
catch (Exception ex)
{
throw new Exception("Error");
}
}
A try-catch processes only one catch block and they are evaluated in order. Therefore, if you really need this functionality you'll need to put a try-catch inside of a try-catch, like this:
using (Entities context = new Entities())
{
try
{
try
{
context.Office.Add(office);
retVal = context.SaveChanges();
}
catch (DbUpdateException ex)
{
SqlException innerException = ex.GetBaseException() as SqlException;
if (innerException != null && innerException.Number == (int)SQLErrorCode.DUPLICATE_UNIQUE_CONSTRAINT)
{
throw
new Exception("Error ocurred");
}
//This is momenty where exception is thrown.
else
{
throw ex;
}
}
}
catch (Exception ex)
{
throw
new Exception("Error");
}
}
Try this:
void YourMethod()
{
using (Entities context = new Entities())
{
try
{
context.Office.Add(office);
retVal = context.SaveChanges();
}
catch (DbUpdateException ex)
{
SqlException innerException = ex.GetBaseException() as SqlException;
if (innerException != null && innerException.Number == (int)SQLErrorCode.DUPLICATE_UNIQUE_CONSTRAINT)
{
throw
new Exception("Error ocurred");
}
//This is momenty where exception is thrown.
else
{
throw ex;
}
}
}
}
Then when you call your method enclose it with try catch block
try
{
YourMethod()
}
catch (Exception ex)
{
throw
new Exception("Error");
}
When you plan to nest your try-catch-block as described by "paul" be aware of the exception type:
using (Entities context = new Entities())
{
try
{
try
{
context.Office.Add(office);
retVal = context.SaveChanges();
}
catch (DbUpdateException ex)
{
SqlException innerException = ex.GetBaseException() as SqlException;
if (innerException != null && innerException.Number == (int)SQLErrorCode.DUPLICATE_UNIQUE_CONSTRAINT)
{
// this exception will be catched too in outer try-catch block <--------
throw new Exception("Error ocurred");
}
//This is momenty where exception is thrown.
else
{
throw ex;
}
}
}
// Catch (DbUpdateException ex) if you plan to have the rethrown exception to be catched <------------
catch (Exception ex)
{
throw new Exception("Error");
}
}
i have a code to restart a service in an event which does other functions too.
I have a try catch in the event for everything within the event like this:
private void btnApply_Click(object sender, EventArgs e)
{
try
{
applyChangesAndCheckRestartService();
}
catch (Exception ex)
{
MessageBox.Show("Error loading page.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void applyChangesAndCheckRestartService()
{
string svrPortNo = CommonCodeClass.getTagValue(CommonCodeClass.xml_SvrPortNoTag, CommonCodeClass.configLocation + CommonCodeClass.configXML);
if (!ApplyChangesForSettings())
{
return;
}
if (svrPortNo != tbSvrPortNo.Text)
{
CommonCodeClass.CheckToRestartService();
}
}
Now if there is an error during ApplyChangesForSettings() i will get an error popup "Error loading page".
If there is an error in CheckToRestartService() i will get the same error because of the try catch.
Is there a better way to handle this.
Like i dont mind the error loading page for ApplyChangesForSettings() but for CheckToRestartService() i would like to see an error like "unable to restart service".
Any suggestions are appreciated.
Thanks
internal static void CheckToRestartService()
{
DialogResult result = MessageBox.Show(CommonCodeClass.resartServiceMessage, "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
if (result == DialogResult.Yes)
{
CommonCodeClass.RestartService(CommonCodeClass.serviceName, 60000);
}
}
Do they throw different exceptions? If they do you could use exception filtering:
private void btnApply_Click(object sender, EventArgs e)
{
try
{
applyChangesAndCheckRestartService();
}
// catch service start exceptions
catch (InvalidOperationException ioex)
{
// display message that couldn't start service
}
// catch rest
catch (Exception ex)
{
MessageBox.Show("Error loading page.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
UPDATE this is assuming you're calling something like ServiceController.Start() which throws InvalidOperationException on failure, you could easily throw this yourself on your own error condition or create your own custom exception.
if (/* service didn't start */)
{
throw new InvalidOperationException("Could not start service.");
}
You either need to
catch the exception in applyChangesAndCheckRestartService
or you could pass an enum by ref f.e. called RestartStatus
enum RestartStatus{success, unableToRestart, unableToApplySettings};
RestartStatus status = RestartStatus.success;
applyChangesAndCheckRestartService(status);
if(status != RestartStatus.success) //....
private void applyChangesAndCheckRestartService(out RestartStatus status)
{
// set the status variable accordingly
}
A third way is to use custom exceptions that you can catch separately.
Well maybe you just need to wrap the different functions with separate try/catch blocks:
try {
if (!ApplyChangesForSettings())
return;
}
catch (Exception ex) {
MessageBox.Show("Error loading page.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
if (svrPortNo != tbSvrPortNo.Text) {
try {
CommonCodeClass.CheckToRestartService();
}
catch (Exception ex) {
MessageBox.Show("Unable to restart services.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
Or, you could consider catching different types of exceptions, if they threw different types:
string errmsg = string.empty;
try {
DoSomething();
}
catch (FooException) {
errmsg = "There was a Foo error";
}
catch (WidgetException) {
errmsg = "There was a problem with a Widget";
}
catch (Exception ex) {
errmsg = "General problem: " + ex.Message;
}
if (!string.IsNullOrEmpty(errmsg))
MessageBox.Show(errmsg);
See also:
Exception Handling
The fastest way to handle this situation is throwing an exception when someone of your internal methods fails and catch the message in the btnApply_Click.
MessageBox.Show(ex.Message, "Error", .....);
The rightest way is to create your own exception type and inside the methods, if there is a fail condition throw your own exception. For example create a class like this
public class RestartServiceException : Exception
{
public RestartServiceException(string message)
: base(message)
{
}
// You could also write other constructors with different parameters and use internal logic
// to process your error message
}
and then, use an instance of that class when the fail condition arise inside your CheckToRestartService method
if(fail == true)
throw new RestartServiceException("The service could not be started because .....");
Below is some of my error logging code. When an exception happens inside my app, I log it to a database. If that database is down or when there's some other problem, I try to log it in an event viewer.
What happens if that event viewer write fails for some reason, too? How do I give up or swallow this new exception?
void SaveLog(string accountId, Exception ex, Category category, Priority priority)
{
try
{
using (var connection = new SqlConnection(…))
{
connection.Open();
command.ExecuteNonQuery();
}
}
catch (Exception exception)
{
// exception while logging!
using (var eventLog = new EventLog { Source = "tis" })
{
eventLog.WriteEntry(
exception.Message + Environment.NewLine +
exception.StackTrace,
EventLogEntryType.Error);
}
}
}
try {
// ...
}
catch (Exception exception) {
try {
// Attempt to write to event log.
}
catch {
}
}