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: "cdak" + alfanumerieke string
    ```
  2. Test API Key: ```al 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: ```al 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; ```

  1. 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: ```json { "field_mappings": [ { "source_field": "E-Mail", "target_field": "email", "required": true, "validation": "email_format" } ] } ```
  2. Pre-validate Data: ```al 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: ```al 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: ```al 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: ```al 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: ```sql -- Add indexes for frequently queried fields CREATE INDEX IXCustomerLastModified ON Customer ("Last Date Modified"); CREATE INDEX IXSalesInvHeaderPostingDate ON "Sales Invoice Header" ("Posting Date"); ```
  2. Batch Processing: ```al 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; ```

  1. Memory Management: ```al 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: ```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: ```al 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; ```

  1. Rollback Procedures: ```al 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;
}