SFTP - ProblemDetected - Upload() - Exception Handling

+1 vote
asked Nov 18, 2014 by cwiegert08 (170 points)
edited Nov 19, 2014

using: Visual Studio 2008 with Rebex Components 2014 R2

Is there a comprehensive document on when ProblemDetected is handled during Upload() and when Upload() solely throws an exception?

For example, I notice if I attempt to upload the same file name twice to the server that Upload() throws an exception AND ProblemDetected is handled. However, when the computer loses network connectivity during upload via Upload(), Upload() throws an exception and ProblemDetected is not handled.

It would be useful to know what types of scenarios would cause these different behaviors for error handling.

I have provided basic code from my test project that illustrates what is described.

Thank you.

private const string IpAddress = "";
private const string UserName = "";
private const string Password = "";
private const string Directory = "";
private const int Port = 22;

private void SftpOnProblemDetected(object sender, SftpProblemDetectedEventArgs sftpProblemDetectedEventArgs)
{
    MessageBox.Show(string.Format("{0}{1}{1}{2}", sftpProblemDetectedEventArgs.Exception, Environment.NewLine,
                                      sftpProblemDetectedEventArgs.ProblemType));
}

private void RebexConnectLoginSetDirectory(Sftp sftp)
{
    sftp.ProblemDetected += SftpOnProblemDetected;

    sftp.Connect(IpAddress, Port, new SshParameters { AuthenticationMethods = SshAuthenticationMethod.Any });

    sftp.Login(UserName, Password);

    sftp.ChangeDirectory(Directory);
}

private void RebexSftpTransferInspectionSingle(string fileFullPath)
{
    if (!File.Exists(fileFullPath))
    {
        MessageBox.Show(string.Format("'{0}' does not exist.", fileFullPath));

        return;
    }

    var fileInfo = new FileInfo(fileFullPath);

    using (var sftp = new Sftp())
    {
        RebexConnectLoginSetDirectory(sftp);

        sftp.Upload(fileInfo.FullName, sftp.GetCurrentDirectory());

        uxError.Text = string.Format("{0}  * Detail: {1}Uploaded '{2}' to '{3}'", uxError.Text, Environment.NewLine, fileInfo.FullName,
                                     sftp.GetCurrentDirectory());

        sftp.Disconnect();
    }

    MessageBox.Show(string.Format("Upload Complete: '{0}'", fileFullPath));
}

private void uxSftpSingleTransfer_Click(object sender, EventArgs e)
{
    try
    {
        Enabled = false;

        string fileFullPath;

        using (var openFileDialog = new OpenFileDialog())
        {
            var dialogResult = openFileDialog.ShowDialog();

            if (dialogResult != DialogResult.OK) return;

            fileFullPath = openFileDialog.FileName;
        }

        if (fileFullPath == null) return;

        var result = MessageBox.Show(string.Format("Are you sure you want to transfer '{0}'?", fileFullPath), "confirm", MessageBoxButtons.YesNo);

        if (result != DialogResult.Yes) return;

        RebexSftpTransferInspectionSingle(fileFullPath);
    }
    catch (Exception exception)
    {
        MessageBox.Show(exception.ToString());
    }
    finally
    {
        Enabled = true;
    }
}
Applies to: Rebex SFTP

2 Answers

+1 vote
answered Nov 19, 2014 by Tomas Knopp (58,580 points)
edited Nov 19, 2014
 
Best answer

For general errors (e.g. networking errors - server closed the connection, invalid arguments, invalid operation exceptions, etc.) we always throw exceptions and we never raise the ProblemDetected event.

Please note that the ProblemDetected event can only be raised during one of the multi-file operations (i.e. Download, Upload, Delete or GetItems methods) AND when one of the file/directory transfer problems defined by the Rebex.IO.TransferProblemType enum happens.

The enum includes values like:

  • FileExists
  • CannotResolveLink
  • InfiniteLoopDetected, etc.

I hope the names are self explaining:

when the event handler is not implemented and the problem is detected during the multi-file operations and it is not treated by the programmer then exception is raised automatically. So in fact, the event is there so that programmers which take advantage of the multi-file operations are able to overcome the situation when "a problem" detected by Rebex Sftp client (like file already exists on the target) in one file would totally cancel the whole operation.

Instead, with the event you are able to specify how to treat this detected problems which are not errors in themselves. If the server closes connection during a multi-file operation then we surely throw an ordinary exception and again the ProblemDetected event will not be raised at all because this is not its purpose.

Actually, I have noted that your program only uses the Upload multi-file operation although you actually only transmit one file at a time. So you could in fact switch to simpler Sftp.PutFile method and ignore the ProblemDetected event completely. I will posted a code snippet below.

commented Nov 19, 2014 by cwiegert08 (170 points)
edited Nov 19, 2014

Tomas, Thanks for the feedback. This answers my question completely.

0 votes
answered Nov 19, 2014 by Tomas Knopp (58,580 points)
edited Nov 19, 2014

Here is the promised code snippet which uses sftp.PutFile method to upload one file:

if (!File.Exists(fileFullPath))
{
    Console.WriteLine(string.Format("'{0}' does not exist.", fileFullPath));
    return;
}

var fileInfo = new FileInfo(fileFullPath);

using (var sftp = new Sftp())
{
    sftp.Connect(IpAddress, Port, new SshParameters { AuthenticationMethods = SshAuthenticationMethod.Any });
    sftp.Login(UserName, Password);
    sftp.ChangeDirectory(Directory);

    sftp.PutFile(fileInfo.FullName, fileInfo.Name);

    Console.WriteLine("{0}  * Detail: {1}Uploaded '{2}' to '{3}'", "", Environment.NewLine, fileInfo.FullName, sftp.GetCurrentDirectory());

    sftp.Disconnect();
}

Console.WriteLine(string.Format("Upload Complete: '{0}'", fileFullPath));
...