Skip to content

Add timeout property to FTP Scope activity#518

Merged
adrianignat13 merged 3 commits intodevelopfrom
feature/ftp-timeout-property
Mar 3, 2026
Merged

Add timeout property to FTP Scope activity#518
adrianignat13 merged 3 commits intodevelopfrom
feature/ftp-timeout-property

Conversation

@adrianignat13
Copy link
Copy Markdown
Member

@adrianignat13 adrianignat13 commented Mar 2, 2026

Problem Statement

The With FTP Session (FTP Scope) activity has no timeout property. FTP/SFTP connections
can hang indefinitely when the remote server is unresponsive, with no way for users to
control connection or operation timeouts.

Analysis

Both underlying libraries already support timeouts natively:

  • FluentFTP (FTP/FTPS): Config.ConnectTimeout, Config.ReadTimeout,
    Config.DataConnectionConnectTimeout, Config.DataConnectionReadTimeout — all int in milliseconds
  • SSH.NET (SFTP): ConnectionInfo.Timeout and SftpClient.OperationTimeout — both TimeSpan

The existing codebase uses InArgument<int> for the Port property with a
null-expression check pattern (Port.Expression == null ? null : (int?)Port.Get(context)).
The Timeout property follows this same pattern for consistency.

Timeout is implemented as per-connection (sets connect/read/data timeouts on the
underlying clients), which is the standard approach matching how Python activities handle
timeout. A cumulative scope-level timeout could be added later if needed.

Considered Use Cases

  • User sets a timeout value — all FTP/SFTP connection and operation timeouts are configured
  • User does not set a timeout — library defaults are preserved (FluentFTP defaults, SSH.NET 30s)
  • FTP with proxy — timeout applies to the proxy-wrapped client equally
  • SFTP — both connection timeout (ConnectionInfo.Timeout) and data operation timeout
    (SftpClient.OperationTimeout) are set to prevent hangs during file transfers
  • Backwards compatibility — existing workflows without timeout continue to work unchanged
    ([DefaultValue(null)] on the new property)

Implementation

Core layer (UiPath.FTP):

  • FtpConfiguration.cs — Added int? Timeout property
  • FtpSession.cs — Apply timeout to 4 FluentFTP config properties (connect, read,
    data connection connect, data connection read) when set
  • SftpSession.cs — Apply timeout to ConnectionInfo.Timeout (connect) and
    SftpClient.OperationTimeout (data operations) when set

Activity layer (UiPath.FTP.Activities):

  • WithFtpSession.cs — Added InArgument<int> Timeout with localized attributes,
    [DefaultValue(null)], wired to FtpConfiguration before the first await

Design layer:

  • WithFtpSessionViewModel.cs — Added DesignInArgument<int> Timeout with OrderIndex
    after Port
  • ActivitiesMetadata.json — Registered Timeout property metadata
  • .resx / .Designer.cs — Added localized display name and description strings

Tests:

  • FtpSessionTests.cs — 2 new tests: timeout applied correctly, defaults preserved
  • SftpSessionTests.cs — 2 new tests: timeout applied to both ConnectionInfo.Timeout
    and OperationTimeout, defaults preserved

How to Test

  1. dotnet test Activities/Activities.FTP.sln — all 14 tests pass
  2. Manual: Create a workflow with With FTP Session, set Timeout to 5000,
    connect to a responsive server — should work normally
  3. Manual: Set Timeout to 1, connect to a slow server — should fail with timeout error
  4. Manual: Leave Timeout empty — should behave identically to current behavior

jira: https://uipath.atlassian.net/browse/STUD-75804

🤖 Generated with Claude Code

Add a configurable Timeout (milliseconds) property to the With FTP Session
activity so users can control connection and operation timeouts for both
FTP/FTPS (FluentFTP) and SFTP (SSH.NET) sessions, preventing indefinite hangs
when remote servers are unresponsive.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Comment thread Activities/FTP/UiPath.FTP.Tests/SessionsTests/SftpSessionTests.cs Fixed
Comment thread Activities/FTP/UiPath.FTP.Tests/SessionsTests/SftpSessionTests.cs Fixed
@adrianignat13 adrianignat13 requested review from alexandru-petre, Copilot and viogroza and removed request for alexandru-petre, Copilot and viogroza March 2, 2026 19:39
@adrianignat13 adrianignat13 marked this pull request as ready for review March 2, 2026 19:40
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a user-configurable timeout to the With FTP Session (FTP Scope) activity, wiring it through the activities layer into the core FTP/SFTP session implementations so hung connections/operations can be bounded.

Changes:

  • Introduces Timeout (ms) in FtpConfiguration and surfaces it as an activity argument on WithFtpSession.
  • Applies the configured timeout to FluentFTP client config (FTP/FTPS) and to SSH.NET connection/operation timeouts (SFTP).
  • Adds unit tests and updates activity metadata + localized resources for the new property.

Reviewed changes

Copilot reviewed 9 out of 10 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
Activities/FTP/UiPath.FTP/FtpConfiguration.cs Adds nullable Timeout (ms) to session configuration.
Activities/FTP/UiPath.FTP/FtpSession.cs Applies configured timeout to FluentFTP connect/read/data timeouts.
Activities/FTP/UiPath.FTP/SftpSession.cs Applies configured timeout to SSH.NET ConnectionInfo.Timeout and SftpClient.OperationTimeout.
Activities/FTP/UiPath.FTP.Activities/WithFtpSession.cs Adds Timeout activity argument and maps it into FtpConfiguration.
Activities/FTP/UiPath.FTP.Activities/NetCore/ViewModels/WithFtpSessionViewModel.cs Adds the Timeout design-time argument and orders it after Port.
Activities/FTP/UiPath.FTP.Activities/Resources/ActivitiesMetadata.json Registers Timeout in activity metadata for Studio/designer.
Activities/FTP/UiPath.FTP.Activities/Properties/UiPath.FTP.Activities.resx Adds localized display name/description for Timeout.
Activities/FTP/UiPath.FTP.Activities/Properties/UiPath.FTP.Activities.Designer.cs Generated resource accessors for the new strings.
Activities/FTP/UiPath.FTP.Tests/SessionsTests/FtpSessionTests.cs Adds coverage for “timeout applied” and “defaults preserved” (FTP).
Activities/FTP/UiPath.FTP.Tests/SessionsTests/SftpSessionTests.cs Adds coverage for “timeout applied” and “defaults preserved” (SFTP).
Files not reviewed (1)
  • Activities/FTP/UiPath.FTP.Activities/Properties/UiPath.FTP.Activities.Designer.cs: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +543 to +549
<data name="Activity_WithFtpSession_Property_Timeout_Description" xml:space="preserve">
<value>The timeout value (in milliseconds) for the FTP connection. If not set, the default timeout of the underlying library is used.</value>
<comment>Property description</comment>
</data>
<data name="Activity_WithFtpSession_Property_Timeout_Name" xml:space="preserve">
<value>Timeout (milliseconds)</value>
<comment>Property name</comment>
Copy link

Copilot AI Mar 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Timeout description says it applies to the “FTP connection”, but With FTP Session can also run in SFTP mode. Consider updating the wording to “FTP/SFTP session” (or similar) to avoid misleading users.

Copilot uses AI. Check for mistakes.
Comment thread Activities/FTP/UiPath.FTP.Tests/SessionsTests/FtpSessionTests.cs Outdated
Comment thread Activities/FTP/UiPath.FTP.Tests/SessionsTests/SftpSessionTests.cs Outdated
Comment thread Activities/FTP/UiPath.FTP.Activities/WithFtpSession.cs Outdated
Comment thread Activities/FTP/UiPath.FTP/SftpSession.cs Outdated
Comment thread Activities/FTP/UiPath.FTP.Tests/SessionsTests/SftpSessionTests.cs Outdated

// When no timeout is set, FluentFTP defaults should be preserved
var defaultClient = new FtpClient();
Assert.Equal(defaultClient.Config.ConnectTimeout, ftpClient.Config.ConnectTimeout);
Copy link

Copilot AI Mar 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This default-preservation test only checks ConnectTimeout. Since the implementation sets 4 FluentFTP timeout properties when configured, consider asserting all 4 match a default FtpClient’s corresponding values when Timeout is not set to prevent partial regressions.

Suggested change
Assert.Equal(defaultClient.Config.ConnectTimeout, ftpClient.Config.ConnectTimeout);
Assert.Equal(defaultClient.Config.ConnectTimeout, ftpClient.Config.ConnectTimeout);
Assert.Equal(defaultClient.Config.ReadTimeout, ftpClient.Config.ReadTimeout);
Assert.Equal(defaultClient.Config.DataConnectionConnectTimeout, ftpClient.Config.DataConnectionConnectTimeout);
Assert.Equal(defaultClient.Config.DataConnectionReadTimeout, ftpClient.Config.DataConnectionReadTimeout);

Copilot uses AI. Check for mistakes.
- Fix timeout description to say "FTP/SFTP" instead of just "FTP"
- Add validation rejecting negative timeout values
- Compute TimeSpan once in SftpSession instead of duplicating conversion
- Assert all 4 FluentFTP timeout defaults in FTP default test
- Assert both ConnectionInfo.Timeout and OperationTimeout defaults in SFTP test
  using fresh client instances instead of hardcoded values
- Rename test credentials to avoid SonarQube hard-coded credential warnings

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Comment thread Activities/FTP/UiPath.FTP.Tests/SessionsTests/SftpSessionTests.cs Fixed
Comment thread Activities/FTP/UiPath.FTP.Tests/SessionsTests/SftpSessionTests.cs Fixed
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 10 changed files in this pull request and generated 5 comments.

Files not reviewed (1)
  • Activities/FTP/UiPath.FTP.Activities/Properties/UiPath.FTP.Activities.Designer.cs: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread Activities/FTP/UiPath.FTP.Activities/WithFtpSession.cs Outdated
Comment thread Activities/FTP/UiPath.FTP.Tests/SessionsTests/FtpSessionTests.cs
Comment thread Activities/FTP/UiPath.FTP.Tests/SessionsTests/FtpSessionTests.cs Outdated
Comment thread Activities/FTP/UiPath.FTP.Tests/SessionsTests/SftpSessionTests.cs Outdated
Comment thread Activities/FTP/UiPath.FTP.Tests/SessionsTests/SftpSessionTests.cs Outdated
- Use localized resource string (InvalidTimeoutException) for timeout
  validation instead of hard-coded English message
- Use ArgumentOutOfRangeException with parameter name for consistency
- Add InternalsVisibleTo on UiPath.FTP for test assembly access
- Add internal Client properties on FtpSession and SftpSession to
  eliminate brittle reflection-based test access
- Dispose all IDisposable clients in tests (sessions, default clients)
- Extract SFTP test config helper to centralize dummy credentials
- Add NOSONAR comments on test-only credential assignments

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud Bot commented Mar 2, 2026

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 10 out of 11 changed files in this pull request and generated 2 comments.

Files not reviewed (1)
  • Activities/FTP/UiPath.FTP.Activities/Properties/UiPath.FTP.Activities.Designer.cs: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

<comment>Property description</comment>
</data>
<data name="Activity_WithFtpSession_Property_Timeout_Description" xml:space="preserve">
<value>The timeout value (in milliseconds) for the FTP/SFTP connection. If not set, the default timeout of the underlying library is used.</value>
Copy link

Copilot AI Mar 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Timeout description says it applies to the FTP/SFTP "connection", but the implementation also sets read/data-connection timeouts for FTP and OperationTimeout for SFTP (i.e., it impacts operations too). Update this localized string to reflect that the timeout applies to both connecting and subsequent read/data operations, so users understand what is affected.

Suggested change
<value>The timeout value (in milliseconds) for the FTP/SFTP connection. If not set, the default timeout of the underlying library is used.</value>
<value>The timeout value (in milliseconds) for establishing the FTP/SFTP connection and for subsequent read and data operations. If not set, the default timeouts of the underlying library are used.</value>

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor

@theloginerror theloginerror Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, we should be very specific; I came up with this variant:
Per-operation timeout in milliseconds for FTP/SFTP connections and data transfers. The activity may involve multiple operations, each timed independently. Leave empty to use the library's default timeouts.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@viogroza Tag to not forget about it :)

public DesignInArgument<int> Port { get; set; }

/// <summary>
/// The connection timeout in milliseconds.
Copy link

Copilot AI Mar 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This summary describes Timeout as a "connection timeout", but the core implementation also applies it to read/data operation timeouts (FTP read/data timeouts, SFTP OperationTimeout). Consider updating the comment to avoid implying it only affects initial connection.

Suggested change
/// The connection timeout in milliseconds.
/// The timeout in milliseconds for establishing the connection and for FTP/SFTP data or read operations.

Copilot uses AI. Check for mistakes.
@adrianignat13 adrianignat13 merged commit 4cc0854 into develop Mar 3, 2026
13 checks passed
@adrianignat13 adrianignat13 deleted the feature/ftp-timeout-property branch March 3, 2026 15:48
<comment>Property description</comment>
</data>
<data name="Activity_WithFtpSession_Property_Timeout_Name" xml:space="preserve">
<value>Timeout (milliseconds)</value>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should adapt the name to something like:
Server Reply Timeout (ms)
or
Response Timeout (ms)
or
Server Response Timeout (ms)
or
Request Timeout (ms)
or
Individual Operation Timeout (ms)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@viogroza Tag to not forget about it :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants