Common Errors

This guide covers the most common issues and errors that can occur when using Credit Device, including diagnostics and solutions.

API Connection Errors

Error 401: Unauthorized

Symptoms:

{
  "error": "unauthorized",
  "message": "Invalid API key or expired token",
  "timestamp": "2026-03-21T10:30:00Z"
}

Possible Causes:

  • Wrong API key entered
  • API key expired or revoked
  • Typo in API key configuration
  • Whitespace before/after API key

Solution:

  1. Verificeer API Key:
    - Open Credit Device Setup
    - Controleer API Key veld op typfouten
    - Remove leading/trailing spaces
    - Verify key format: "cd_ak_" + alfanumerieke string
  2. Test API Key:
    procedure TestAPIKey()
    var
        Setup: Record "QTEAM Credit Device Setup";
        RestMgt: Codeunit "QTEAM REST Web service Mgt";
        Response: Text;
    begin
        Setup.Get();
        if RestMgt.SendRequest('GET', 'health', '', Response) then
            Message('API Key is valid')
        else
            Error('API Key validation failed');
    end;
  3. Contact CreditDevice Support:
    • Request new API key
    • Verify account status
    • Check rate limits

Error 429: Rate Limit Exceeded

Symptomen:

{
  "error": "rate_limit_exceeded", 
  "message": "Too many requests. Limit: 60/minute",
  "retry_after": 30
}

Oplossing:

  1. Implement Rate Limiting:
    procedure SendWithRateLimit(Method: Text; Endpoint: Text; Body: Text; var Response: Text): Boolean
    var
        LastCallTime: DateTime;
        MinInterval: Integer;
    begin
        MinInterval := 1000; // 1 second between calls
    
        if CurrentDateTime - LastCallTime < MinInterval then
            Sleep(MinInterval - (CurrentDateTime - LastCallTime));
    
        LastCallTime := CurrentDateTime;
        exit(SendRequest(Method, Endpoint, Body, Response));
    end;
  2. Optimize Batch Sizes:
    • Reduce records per API call
    • Increase interval between calls
    • Use off-peak hours for bulk operations

Error 500: Internal Server Error

Symptomen:

  • Intermittent failures
  • Timeout errors
  • "Service temporarily unavailable" messages

Immediate Actions:

  1. Check CreditDevice Status Page
  2. Implement retry logic with exponential backoff
  3. Cache successful responses where appropriate
  4. Contact technical support if persistent

Retry Implementation:

procedure SendWithRetry(Method: Text; Endpoint: Text; Body: Text; var Response: Text): Boolean
var
    Attempt: Integer;
    Success: Boolean;
    DelaySeconds: Integer;
begin
    DelaySeconds := 2;
    
    for Attempt := 1 to 5 do begin
        Success := SendRequest(Method, Endpoint, Body, Response);
        
        if Success then
            exit(true);
            
        Sleep(DelaySeconds * 1000);
        DelaySeconds := DelaySeconds * 2; // Exponential backoff
    end;
    
    exit(false);
end;

Data Import Fouten

Import Validation Errors

Error: "Required field missing"

Symptomen:

{
  "error": "validation_failed",
  "details": [{
    "field": "customer.email",
    "code": "required",
    "message": "Email field is required but missing"
  }]
}

Oplossing:

  1. Check Data Mapping:
    {
      "field_mappings": [
        {
          "source_field": "E-Mail",
          "target_field": "email",
          "required": true,
          "validation": "email_format"
        }
      ]
    }
  2. Pre-validate Data:
    procedure ValidateCustomerData(Customer: Record Customer): Boolean
    var
        ValidationErrors: List of [Text];
    begin
        if Customer."E-Mail" = '' then
            ValidationErrors.Add('Email is required');
    
        if not IsValidEmail(Customer."E-Mail") then
            ValidationErrors.Add('Email format is invalid');
    
        if ValidationErrors.Count > 0 then begin
            ShowValidationErrors(ValidationErrors);
            exit(false);
        end;
    
        exit(true);
    end;

Bulk Import Timeout

Symptomen:

  • Import stopt na lange tijd
  • "Request timeout" error messages
  • Partially completed imports

Oplossing:

  1. Reduce Batch Size:
    procedure OptimizeBatchSize(TotalRecords: Integer): Integer
    begin
        case TotalRecords of
            0..100:
                exit(50);
            101..1000:
                exit(100);
            1001..10000:
                exit(250);
            else
                exit(500);
        end;
    end;
  2. Implement Progress Tracking:
    procedure ImportWithProgress(var Customer: Record Customer)
    var
        ProgressDialog: Dialog;
        Counter: Integer;
        Total: Integer;
    begin
        Total := Customer.Count;
        ProgressDialog.Open('Processing customers: #1### of #2###');
    
        if Customer.FindSet() then
            repeat
                Counter += 1;
                ProgressDialog.Update(1, Counter);
                ProgressDialog.Update(2, Total);
    
                ProcessSingleCustomer(Customer);
            until Customer.Next() = 0;
    
        ProgressDialog.Close();
    end;

Job Queue Problemen

Job Queue Entry wordt niet uitgevoerd

Diagnostic Steps:

  1. Check Job Queue Status:
    procedure DiagnoseJobQueue()
    var
        JobQueueEntry: Record "Job Queue Entry";
    begin
        JobQueueEntry.SetRange("Object ID to Run", 11195976);
        if JobQueueEntry.FindFirst() then begin
            Message('Status: %1\Last Error: %2', JobQueueEntry.Status, JobQueueEntry."Error Message");
        end else begin
            Message('No Credit Device job queue entries found');
        end;
    end;
  2. Verify Job Queue Service:
    • Check if job queue service is running
    • Verify user permissions for job queue
    • Check job queue category configuration

Common Solutions:

Problem: Job repeatedly fails

Solution:
1. Check "Error Message" field in job queue entry
2. Verify all dependencies (API connectivity, permissions)
3. Test codeunit manually
4. Adjust "Maximum No. of Attempts" if needed

Problem: Job not starting

Solution:
1. Verify "Earliest Start Date/Time" is not in future
2. Check "Status" = "Ready"
3. Ensure job queue service user has proper permissions
4. Restart job queue service if necessary

Job Queue Error Logging

procedure LogJobQueueError(ErrorMessage: Text; JobQueueEntryID: Guid)
var
    ErrorLog: Record "Credit Device Error Log";
begin
    ErrorLog.Init();
    ErrorLog."Entry No." := 0; // Auto-increment
    ErrorLog."Error Type" := "Job Queue";
    ErrorLog."Error Message" := ErrorMessage;
    ErrorLog."Job Queue Entry ID" := JobQueueEntryID;
    ErrorLog."Occurred At" := CurrentDateTime;
    ErrorLog.Insert(true);
end;

Webhook Problemen

Webhook Events Not Received

Diagnostic Checklist:

  • Webhook URL is publicly accessible
  • HTTPS certificate is valid
  • Firewall allows inbound traffic
  • Business Central service is running
  • Webhook endpoint is registered correctly

URL Accessibility Test:

# Test from external location
curl -X POST https://yourdomain.businesscentral.dynamics.com/webhook/creditdevice \
  -H "Content-Type: application/json" \
  -H "X-CreditDevice-Event: test" \
  -d '{"test": true}'

Business Central Webhook Handler:

procedure ProcessInboundWebhook(EventType: Text; Payload: Text)
var
    WebhookLog: Record "Credit Device Webhook Log";
begin
    // Log all incoming webhooks
    WebhookLog.Init();
    WebhookLog."Entry No." := 0;
    WebhookLog."Event Type" := EventType;
    WebhookLog."Payload" := Payload;
    WebhookLog."Received At" := CurrentDateTime;
    WebhookLog.Insert(true);
    
    // Process event
    case EventType of
        'customer.updated':
            ProcessCustomerUpdate(Payload);
        'invoice.payment_received':
            ProcessPaymentUpdate(Payload);
    end;
end;

Performance Problemen

Slow Import Performance

Performance Diagnostics:

procedure MeasureImportPerformance()
var
    StartTime: DateTime;
    EndTime: DateTime;
    Duration: Integer;
    RecordsProcessed: Integer;
begin
    StartTime := CurrentDateTime;
    
    // Perform import operation
    RecordsProcessed := ExecuteImport();
    
    EndTime := CurrentDateTime;
    Duration := EndTime - StartTime;
    
    Message('Imported %1 records in %2 ms (%.3 records/second)', 
        RecordsProcessed, Duration, RecordsProcessed / (Duration / 1000));
end;

Optimization Strategies:

  1. Database Optimization:
    -- Add indexes for frequently queried fields
    CREATE INDEX IX_Customer_LastModified ON Customer ("Last Date Modified");
    CREATE INDEX IX_SalesInvHeader_PostingDate ON "Sales Invoice Header" ("Posting Date");
  2. Batch Processing:
    procedure ProcessInBatches(var RecordRef: RecordRef; BatchSize: Integer)
    var
        Counter: Integer;
        Batch: List of [RecordRef];
    begin
        if RecordRef.FindSet() then
            repeat
                Batch.Add(RecordRef);
                Counter += 1;
    
                if Counter = BatchSize then begin
                    ProcessBatch(Batch);
                    Batch := Batch; // Clear list
                    Counter := 0;
                end;
            until RecordRef.Next() = 0;
    
        // Process remaining records
        if Batch.Count > 0 then
            ProcessBatch(Batch);
    end;
  3. Memory Management:
    procedure OptimizeMemoryUsage()
    begin
        // Use streaming for large JSON processing
        // Clear temporary records frequently
        // Minimize object instantiation in loops
    end;

Network en Connectivity

SSL/TLS Certificate Errors

Symptoms:

  • "SSL handshake failed"
  • "Certificate validation error"
  • "Untrusted certificate authority"

Resolution:

  1. Update certificate store
  2. Verify certificate chain
  3. Check certificate expiration
  4. Test with curl or PowerShell:
    Invoke-WebRequest -Uri "https://api.creditdevice.com/v1/health" -Method GET

Firewall Configuration

Required Outbound Rules:

Protocol: HTTPS (TCP 443)
Destination: api.creditdevice.com
Direction: Outbound
Action: Allow

Required Inbound Rules (voor webhooks):

Protocol: HTTPS (TCP 443)
Source: CreditDevice platform IPs
Destination: Your Business Central webhook endpoint
Direction: Inbound
Action: Allow

Error Recovery Procedures

Automated Recovery

codeunit 50102 "Credit Device Recovery"
{
    procedure AutoRecovery()
    var
        ErrorLog: Record "Credit Device Error Log";
        RecoveryResult: Boolean;
    begin
        ErrorLog.SetRange("Recovery Attempted", false);
        ErrorLog.SetRange("Error Type", ErrorLog."Error Type"::"Temporary");
        
        if ErrorLog.FindSet() then
            repeat
                RecoveryResult := AttemptRecovery(ErrorLog);
                ErrorLog."Recovery Attempted" := true;
                ErrorLog."Recovery Successful" := RecoveryResult;
                ErrorLog."Recovery Attempted At" := CurrentDateTime;
                ErrorLog.Modify();
            until ErrorLog.Next() = 0;
    end;
    
    local procedure AttemptRecovery(ErrorLog: Record "Credit Device Error Log"): Boolean
    begin
        case ErrorLog."Error Code" of
            'RATE_LIMITED':
                exit(RetryAfterDelay(ErrorLog."Operation Context"));
            'TIMEOUT':
                exit(RetryWithSmallerBatch(ErrorLog."Operation Context"));
            'NETWORK_ERROR':
                exit(RetryWithBackoff(ErrorLog."Operation Context"));
            else
                exit(false);
        end;
    end;
}

Manual Recovery Procedures

For Critical Failures:

  1. Data Integrity Check:
    procedure VerifyDataIntegrity()
    var
        Customer: Record Customer;
        ImportLog: Record "Credit Device Import Log";
        MissingRecords: Integer;
    begin
        // Compare record counts
        Customer.SetFilter("Last Date Modified", '>=%1', ImportLog."Import Date");
        MissingRecords := ImportLog."Expected Records" - Customer.Count;
    
        if MissingRecords > 0 then
            Error('Data integrity issue: %1 records missing', MissingRecords);
    end;
  2. Rollback Procedures:
    procedure RollbackFailedImport(ImportBatchID: Code[50])
    var
        ImportLog: Record "Credit Device Import Log";
    begin
        // Restore from backup
        // Remove partially imported data
        // Reset import status
    end;

Support Escalation

When to Contact Support

Immediate Escalation (Severity 1):

  • Complete service outage
  • Data corruption detected
  • Security breach suspected
  • Financial data discrepancies

Standard Support (Severity 2-3):

  • Performance degradation
  • Intermittent failures
  • Configuration questions
  • Feature requests

Information to Provide

Essential Information:

1. Environment Details:
   - Business Central version
   - Credit Device app version
   - Deployment type (SaaS/OnPrem)
   
2. Error Details:
   - Exact error message
   - Timestamp of occurrence
   - Steps to reproduce
   - Frequency of issue
   
3. System Context:
   - Recent changes made
   - Data volumes involved
   - Network configuration
   - Other integrated systems

Log Files to Include:

  • Credit Device error logs
  • Business Central event logs
  • Job queue execution logs
  • API call traces

Self-Diagnosis Tools

codeunit 50103 "Credit Device Diagnostics"
{
    procedure RunFullDiagnostics(): Text
    var
        DiagnosticResult: TextBuilder;
    begin
        DiagnosticResult.AppendLine('=== Credit Device Diagnostics ===');
        DiagnosticResult.AppendLine(CheckAPIConnectivity());
        DiagnosticResult.AppendLine(CheckConfiguration());
        DiagnosticResult.AppendLine(CheckJobQueueStatus());
        DiagnosticResult.AppendLine(CheckDataIntegrity());
        DiagnosticResult.AppendLine(CheckPerformanceMetrics());
        
        exit(DiagnosticResult.ToText());
    end;
}