Table of Contents

Troubleshooting

Common issues and solutions when testing modules.

Common Issues

1. Timeout Exceptions

Problem: OperationCanceledException when waiting for results

Symptoms:

System.OperationCanceledException: The operation was canceled.

Solutions:

  • Increase timeout in SetupFlow(timeout: 30000)
  • Check module processing - Verify your module is actually sending output
  • Verify message routing - Ensure messages reach the correct output
  • Check async operations - Ensure all async operations complete properly

Example Fix:

// Increase timeout for slow operations
var flow = module.SetupFlow(timeout: 30000);

2. Channel Closed Exceptions

Problem: ChannelClosedException when reading results

Symptoms:

System.Threading.Channels.ChannelClosedException: The channel has been closed.

Solutions:

  • Call Start() first - Ensure you call Start() before sending messages
  • Don't call Stop() early - Don't call Stop() before retrieving all expected results
  • Check disposal order - Verify module isn't disposed prematurely

Example Fix:

[Fact]
public async Task CorrectOrder()
{
    var flow = module.SetupFlow();
    
    await flow.Start();           // 1. Start first
    await flow.Receive(message);  // 2. Send messages
    var result = await flow.GetNextResult();  // 3. Get results
    await flow.Stop();            // 4. Stop last
}

3. Missing Results

Problem: Expected results are not available

Symptoms:

  • Test hangs waiting for results
  • Fewer results than expected
  • Null or empty results

Solutions:

  • Verify output routing - Check if your module sends to the correct output index
  • Check module initialization - Ensure module requires specific initialization
  • Verify dependencies - Ensure all dependencies (credentials, resources) are properly set up
  • Check message filters - Verify module isn't filtering out messages

Debugging Steps:

[Fact]
public async Task DebugMissingResults()
{
    var module = new MyModule();
    module.Settings.OutputEnabled = true; // Ensure output is enabled
    
    var flow = module.SetupFlow(timeout: 60000); // Long timeout for debugging

    var startResult = await flow.Start();
    Console.WriteLine($"Start result: {startResult.IsSuccess}");
    
    await flow.Receive(message);
    Console.WriteLine("Message sent");
    
    var result = await flow.GetNextResult();
    Console.WriteLine($"Result received: {result != null}");
}

4. Credential/Resource Loading Issues

Problem: Module can't access credentials or resources

Symptoms:

  • Null reference exceptions when accessing credentials
  • Resources not found
  • Authentication failures

Solutions:

  • Verify IDs match - Credential/resource IDs must match what your module expects
  • Check file paths - Ensure file paths are correct for credential loading
  • Verify JSON format - Ensure JSON serialization/deserialization works correctly
  • Use correct types - Ensure credential types match module expectations

Example:

[Fact]
public async Task TestCredentialLoading()
{
    var module = new MyModule();
    
    // Ensure ID matches what module expects
    var credentialId = module.Settings.CredentialId;
    var credential = new MyCredential
    {
        Id = credentialId,
        ApiKey = "test-key"
    };
    
    var flow = module.SetupFlow()
        .WithCredential(credential);

    await flow.Start();
    // Now credential is accessible
}

5. Null Reference Exceptions

Problem: Null reference when accessing message properties

Symptoms:

System.NullReferenceException: Object reference not set to an instance of an object.

Solutions:

  • Check property existence - Use Has() before Get()
  • Set required properties - Ensure test messages contain all required properties
  • Handle null values - Use GetOrDefault() for optional properties

Example:

[Fact]
public async Task SafePropertyAccess()
{
    var flow = module.SetupFlow();
    await flow.Start();

    await flow.Receive(new FlowMessage());
    var result = await flow.GetNextResult();

    // Safe property access
    if (result.Has("data.value"))
    {
        var value = result.Get<string>("data.value");
        Assert.NotNull(value);
    }
}

Debugging Tips

1. Enable Debug Output

Add logging to see what's happening:

[Fact]
public async Task DebugTest()
{
    var module = new MyModule();
    var flow = module.SetupFlow();

    await flow.Start();
    
    var message = new FlowMessage();
    message.Set("data", "test");
    Console.WriteLine($"Sending message: {message.ToJSON()}");
    
    await flow.Receive(message);
    
    var result = await flow.GetNextResult();
    Console.WriteLine($"Received result: {result.ToJSON()}");
    
    await flow.Stop();
}

2. Check Module State

Verify module configuration before testing:

[Fact]
public async Task VerifyModuleState()
{
    var module = new MyModule();
    var flow = module.SetupFlow();

    // Verify settings
    Assert.NotNull(module.Settings);
    Assert.Equal("expected-value", module.Settings.Property);

    // Verify credentials
    Assert.True(module.Settings.Credentials.Any());
    
    await flow.Start();
    // Continue test
}

3. Test Individual Components

Test components separately to isolate issues:

[Fact]
public void TestCredentialLoading()
{
    // Test credential loading separately
    var json = File.ReadAllText("test-cred.json");
    var credential = JsonSerializer.Deserialize<MyCredential>(json);
    
    Assert.NotNull(credential);
    Assert.NotNull(credential.ApiKey);
}

[Fact]
public async Task TestModuleProcessing()
{
    // Test module in isolation
    var module = new MyModule();
    // ...
}

4. Use Breakpoints

Set breakpoints in your module code and step through execution:

[Fact]
public async Task DebugWithBreakpoints()
{
    var module = new MyModule();
    var flow = module.SetupFlow(timeout: 300000); // Long timeout for debugging

    await flow.Start();
    
    // Set breakpoint here, then step into your module
    await flow.Receive(message);
    
    var result = await flow.GetNextResult();
}

5. Verify Async Operations

Ensure all async operations complete:

[Fact]
public async Task VerifyAsyncCompletion()
{
    var module = new MyModule();
    var flow = module.SetupFlow();

    var startTask = flow.Start();
    Assert.False(startTask.IsCompleted); // Should be running
    
    var startResult = await startTask;
    Assert.True(startTask.IsCompleted); // Should be complete
    Assert.True(startResult.IsSuccess);
}

Getting Help

If you continue to experience issues:

  1. Check the SDK version compatibility
  2. Review the module implementation for common mistakes
  3. Consult the Best Practices guide
  4. Review similar tests in the SDK examples
  5. Contact Crosser support with a minimal reproduction example