Fehlerbehebung

Lösungen für häufige Probleme und Fehlerbehebungstipps

Fehlerbehebung

Häufige Probleme und deren Lösungen bei der Verwendung von Qwen Image Edit.

🔐 Authentifizierungsfehler

Ungültiger API-Schlüssel

Problem: INVALID_API_KEY - Der API-Schlüssel ist ungültig oder abgelaufen.

Symptome:

Error: INVALID_API_KEY - Der bereitgestellte API-Schlüssel ist ungültig

Lösungen:

  1. API-Schlüssel überprüfen:
// Stelle sicher, dass der API-Schlüssel korrekt ist
const editor = new QwenImageEdit({
  apiKey: 'qwen_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', // Korrektes Format
  region: 'eu-west-1'
});

// Überprüfe Umgebungsvariablen
console.log('API-Schlüssel:', process.env.QWEN_API_KEY?.substring(0, 10) + '...');
  1. Neuen API-Schlüssel generieren:

    • Besuche das Qwen Dashboard
    • Gehe zu "API-Schlüssel"
    • Erstelle einen neuen Schlüssel
    • Aktualisiere deine Umgebungsvariablen
  2. Schlüssel-Format validieren:

function validateAPIKey(apiKey) {
  if (!apiKey) {
    throw new Error('API-Schlüssel ist erforderlich');
  }
  
  if (!apiKey.startsWith('qwen_')) {
    throw new Error('API-Schlüssel muss mit "qwen_" beginnen');
  }
  
  if (apiKey.length !== 40) {
    throw new Error('API-Schlüssel muss 40 Zeichen lang sein');
  }
  
  return true;
}

try {
  validateAPIKey(process.env.QWEN_API_KEY);
  console.log('✅ API-Schlüssel ist gültig');
} catch (error) {
  console.error('❌ API-Schlüssel-Fehler:', error.message);
}

Nicht unterstützte Region

Problem: UNSUPPORTED_REGION - Die angegebene Region wird nicht unterstützt.

Symptome:

Error: UNSUPPORTED_REGION - Region 'us-west-1' wird nicht unterstützt

Lösung:

// Verwende eine unterstützte Region
const supportedRegions = ['eu-west-1', 'us-east-1', 'ap-southeast-1'];

const editor = new QwenImageEdit({
  apiKey: process.env.QWEN_API_KEY,
  region: 'eu-west-1' // Verwende eine gültige Region
});

// Automatische Regionserkennung
function getOptimalRegion() {
  const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
  
  if (timezone.includes('Europe')) return 'eu-west-1';
  if (timezone.includes('America')) return 'us-east-1';
  if (timezone.includes('Asia')) return 'ap-southeast-1';
  
  return 'eu-west-1'; // Standard-Fallback
}

const editor = new QwenImageEdit({
  apiKey: process.env.QWEN_API_KEY,
  region: getOptimalRegion()
});

💳 Kontingent- und Rate-Limiting-Probleme

Nicht genügend Credits

Problem: INSUFFICIENT_CREDITS - Nicht genügend Credits für die Operation.

Symptome:

Error: INSUFFICIENT_CREDITS - Aktueller Kontostand: 5 Credits, benötigt: 10 Credits

Lösungen:

  1. Credit-Status überprüfen:
async function checkCredits() {
  try {
    const status = await editor.getAccountStatus();
    console.log('Verfügbare Credits:', status.credits);
    console.log('Monatliches Limit:', status.monthlyLimit);
    console.log('Verwendete Credits:', status.usedCredits);
    
    if (status.credits < 10) {
      console.warn('⚠️ Niedrige Credits! Bitte lade dein Konto auf.');
    }
  } catch (error) {
    console.error('Fehler beim Abrufen des Credit-Status:', error);
  }
}

await checkCredits();
  1. Credit-Verbrauch optimieren:
// Verwende niedrigere Qualitätseinstellungen für weniger Credits
const result = await editor.editText({
  image: './bild.jpg',
  prompt: 'Einfache Textbearbeitung',
  quality: 'medium', // Statt 'high'
  maxWidth: 1024     // Kleinere Auflösung
});

// Batch-Verarbeitung für Effizienz
const results = await editor.batchProcess({
  operations: multipleOperations,
  optimizeCredits: true // Automatische Optimierung
});

Rate-Limit überschritten

Problem: RATE_LIMIT_EXCEEDED - Zu viele Anfragen in kurzer Zeit.

Symptome:

Error: RATE_LIMIT_EXCEEDED - Rate-Limit überschritten. Versuche es in 60 Sekunden erneut.

Lösungen:

  1. Rate-Limiting implementieren:
import pLimit from 'p-limit';

// Begrenze gleichzeitige Anfragen
const limit = pLimit(2); // Maximal 2 gleichzeitige Anfragen

const bilder = ['bild1.jpg', 'bild2.jpg', 'bild3.jpg'];

const results = await Promise.all(
  bilder.map(bild => 
    limit(async () => {
      return await editor.editText({
        image: bild,
        prompt: 'Bearbeite das Bild'
      });
    })
  )
);
  1. Exponential Backoff:
import pRetry from 'p-retry';

async function editTextWithBackoff(options) {
  return pRetry(async () => {
    try {
      return await editor.editText(options);
    } catch (error) {
      if (error.code === 'RATE_LIMIT_EXCEEDED') {
        const retryAfter = error.retryAfter || 60;
        console.log(`Rate-Limit erreicht, warte ${retryAfter} Sekunden...`);
        throw error; // Wird von pRetry behandelt
      }
      throw new pRetry.AbortError(error);
    }
  }, {
    retries: 5,
    factor: 2,
    minTimeout: 1000,
    maxTimeout: 60000
  });
}

🖼️ Bildbezogene Probleme

Bild zu groß

Problem: IMAGE_TOO_LARGE - Das Bild überschreitet die maximale Dateigröße.

Symptome:

Error: IMAGE_TOO_LARGE - Bildgröße: 15MB, Maximum: 10MB

Lösungen:

  1. Automatische Bildkomprimierung:
import sharp from 'sharp';

async function compressImage(inputPath, maxSizeBytes = 10 * 1024 * 1024) {
  const metadata = await sharp(inputPath).metadata();
  
  if (metadata.size <= maxSizeBytes) {
    return inputPath; // Bereits klein genug
  }
  
  const outputPath = inputPath.replace(/\.(jpg|jpeg|png)$/i, '_compressed.$1');
  
  // Starte mit 85% Qualität
  let quality = 85;
  let compressedSize = maxSizeBytes + 1;
  
  while (compressedSize > maxSizeBytes && quality > 20) {
    await sharp(inputPath)
      .jpeg({ quality })
      .toFile(outputPath);
    
    const stats = await fs.stat(outputPath);
    compressedSize = stats.size;
    
    if (compressedSize > maxSizeBytes) {
      quality -= 10;
    }
  }
  
  console.log(`Bild komprimiert: ${metadata.size} → ${compressedSize} Bytes`);
  return outputPath;
}

// Verwendung
const compressedImage = await compressImage('./grosses-bild.jpg');
const result = await editor.editText({
  image: compressedImage,
  prompt: 'Bearbeite das Bild'
});
  1. Intelligente Größenanpassung:
async function resizeForProcessing(imagePath) {
  const metadata = await sharp(imagePath).metadata();
  
  // Berechne optimale Größe
  const maxDimension = 2048;
  const ratio = Math.min(
    maxDimension / metadata.width,
    maxDimension / metadata.height,
    1 // Nicht vergrößern
  );
  
  if (ratio < 1) {
    const newWidth = Math.round(metadata.width * ratio);
    const newHeight = Math.round(metadata.height * ratio);
    
    const outputPath = imagePath.replace(/\.(jpg|jpeg|png)$/i, '_resized.$1');
    
    await sharp(imagePath)
      .resize(newWidth, newHeight, {
        kernel: sharp.kernel.lanczos3,
        withoutEnlargement: true
      })
      .jpeg({ quality: 90 })
      .toFile(outputPath);
    
    console.log(`Bild verkleinert: ${metadata.width}x${metadata.height} → ${newWidth}x${newHeight}`);
    return outputPath;
  }
  
  return imagePath;
}

Nicht unterstütztes Bildformat

Problem: UNSUPPORTED_FORMAT - Das Bildformat wird nicht unterstützt.

Symptome:

Error: UNSUPPORTED_FORMAT - Format 'bmp' wird nicht unterstützt. Unterstützte Formate: jpg, png, webp

Lösung:

import sharp from 'sharp';

async function convertToSupportedFormat(inputPath) {
  const metadata = await sharp(inputPath).metadata();
  
  const supportedFormats = ['jpeg', 'jpg', 'png', 'webp'];
  
  if (supportedFormats.includes(metadata.format)) {
    return inputPath; // Bereits unterstützt
  }
  
  console.log(`Konvertiere ${metadata.format} zu JPEG...`);
  
  const outputPath = inputPath.replace(/\.[^.]+$/, '.jpg');
  
  await sharp(inputPath)
    .jpeg({ quality: 90 })
    .toFile(outputPath);
  
  return outputPath;
}

// Verwendung
const convertedImage = await convertToSupportedFormat('./bild.bmp');
const result = await editor.editText({
  image: convertedImage,
  prompt: 'Bearbeite das Bild'
});

🌐 Netzwerkprobleme

Verbindungstimeout

Problem: TIMEOUT - Die Anfrage hat das Zeitlimit überschritten.

Symptome:

Error: TIMEOUT - Anfrage nach 30000ms abgebrochen

Lösungen:

  1. Timeout erhöhen:
const editor = new QwenImageEdit({
  apiKey: process.env.QWEN_API_KEY,
  timeout: 120000, // 2 Minuten für komplexe Operationen
  region: 'eu-west-1'
});
  1. Adaptive Timeouts:
function getTimeoutForOperation(operation, imageSize) {
  const baseTimeout = 30000; // 30 Sekunden
  
  // Anpassung basierend auf Operation
  const operationMultipliers = {
    editText: 1,
    editElement: 1.5,
    transferStyle: 2,
    analyzeImage: 0.5
  };
  
  // Anpassung basierend auf Bildgröße (in MB)
  const sizeMultiplier = Math.max(1, imageSize / (5 * 1024 * 1024));
  
  const timeout = baseTimeout * 
    (operationMultipliers[operation] || 1) * 
    sizeMultiplier;
  
  return Math.min(timeout, 300000); // Maximal 5 Minuten
}

// Verwendung
const imageSize = fs.statSync('./grosses-bild.jpg').size;
const timeout = getTimeoutForOperation('transferStyle', imageSize);

const editor = new QwenImageEdit({
  apiKey: process.env.QWEN_API_KEY,
  timeout: timeout
});

Netzwerkfehler

Problem: NETWORK_ERROR - Allgemeine Netzwerkverbindungsprobleme.

Symptome:

Error: NETWORK_ERROR - Verbindung zum Server fehlgeschlagen

Lösungen:

  1. Verbindung testen:
async function testConnection() {
  try {
    const response = await fetch('https://api.qwen.com/health');
    if (response.ok) {
      console.log('✅ Verbindung zur API erfolgreich');
    } else {
      console.log('❌ API antwortet mit Fehler:', response.status);
    }
  } catch (error) {
    console.log('❌ Netzwerkfehler:', error.message);
  }
}

await testConnection();
  1. Retry-Mechanismus:
class RobustEditor {
  constructor(options) {
    this.editor = new QwenImageEdit(options);
    this.maxRetries = options.maxRetries || 3;
  }
  
  async editTextWithRetry(options) {
    let lastError;
    
    for (let attempt = 1; attempt <= this.maxRetries; attempt++) {
      try {
        console.log(`Versuch ${attempt}/${this.maxRetries}`);
        return await this.editor.editText(options);
      } catch (error) {
        lastError = error;
        
        if (this.isRetryableError(error) && attempt < this.maxRetries) {
          const delay = Math.min(1000 * Math.pow(2, attempt - 1), 10000);
          console.log(`Warte ${delay}ms vor erneutem Versuch...`);
          await new Promise(resolve => setTimeout(resolve, delay));
        } else {
          break;
        }
      }
    }
    
    throw lastError;
  }
  
  isRetryableError(error) {
    const retryableCodes = [
      'NETWORK_ERROR',
      'TIMEOUT',
      'SERVICE_UNAVAILABLE',
      'RATE_LIMIT_EXCEEDED'
    ];
    
    return retryableCodes.includes(error.code);
  }
}

⚙️ Verarbeitungsfehler

Verarbeitung fehlgeschlagen

Problem: PROCESSING_FAILED - Die Bildverarbeitung ist fehlgeschlagen.

Symptome:

Error: PROCESSING_FAILED - Bildverarbeitung konnte nicht abgeschlossen werden

Lösungen:

  1. Eingabe validieren:
async function validateImageForProcessing(imagePath) {
  try {
    const metadata = await sharp(imagePath).metadata();
    
    // Prüfe Bildformat
    const supportedFormats = ['jpeg', 'jpg', 'png', 'webp'];
    if (!supportedFormats.includes(metadata.format)) {
      throw new Error(`Nicht unterstütztes Format: ${metadata.format}`);
    }
    
    // Prüfe Bildgröße
    if (metadata.width < 64 || metadata.height < 64) {
      throw new Error('Bild zu klein (Minimum: 64x64 Pixel)');
    }
    
    if (metadata.width > 4096 || metadata.height > 4096) {
      throw new Error('Bild zu groß (Maximum: 4096x4096 Pixel)');
    }
    
    // Prüfe Dateigröße
    const stats = await fs.stat(imagePath);
    if (stats.size > 10 * 1024 * 1024) {
      throw new Error('Datei zu groß (Maximum: 10MB)');
    }
    
    console.log('✅ Bild-Validierung erfolgreich');
    return true;
  } catch (error) {
    console.error('❌ Bild-Validierung fehlgeschlagen:', error.message);
    throw error;
  }
}

// Verwendung
try {
  await validateImageForProcessing('./bild.jpg');
  const result = await editor.editText({
    image: './bild.jpg',
    prompt: 'Bearbeite das Bild'
  });
} catch (error) {
  console.error('Fehler:', error.message);
}

Inhalt nicht erkannt

Problem: CONTENT_NOT_DETECTED - Der angegebene Inhalt wurde im Bild nicht gefunden.

Symptome:

Error: CONTENT_NOT_DETECTED - Text "Hallo Welt" wurde im Bild nicht gefunden

Lösungen:

  1. Bildanalyse vor Bearbeitung:
async function analyzeBeforeEdit(imagePath, prompt) {
  // Erst analysieren
  const analysis = await editor.analyzeImage({
    image: imagePath,
    analysisTypes: ['text', 'objects']
  });
  
  console.log('Erkannter Text:', analysis.analysis.text?.content);
  console.log('Erkannte Objekte:', analysis.analysis.objects?.map(o => o.name));
  
  // Prompt anpassen basierend auf Analyse
  if (analysis.analysis.text?.content) {
    console.log('✅ Text erkannt, Bearbeitung möglich');
  } else {
    console.log('⚠️ Kein Text erkannt, verwende Element-Bearbeitung');
    
    // Fallback zu Element-Bearbeitung
    return await editor.editElement({
      image: imagePath,
      prompt: prompt
    });
  }
  
  return await editor.editText({
    image: imagePath,
    prompt: prompt
  });
}
  1. Flexiblere Prompts:
// Statt spezifischer Text-Suche
const result = await editor.editText({
  image: './bild.jpg',
  prompt: 'Ändere "Hallo Welt" zu "Guten Tag"' // Kann fehlschlagen
});

// Verwende allgemeinere Anweisungen
const result = await editor.editText({
  image: './bild.jpg',
  prompt: 'Ändere den Haupttext zu "Guten Tag"' // Flexibler
});

🐛 Debug-Tools

Detailliertes Logging

import winston from 'winston';

// Winston-Logger konfigurieren
const logger = winston.createLogger({
  level: 'debug',
  format: winston.format.combine(
    winston.format.timestamp(),
    winston.format.errors({ stack: true }),
    winston.format.printf(({ timestamp, level, message, stack }) => {
      return `${timestamp} [${level.toUpperCase()}]: ${message}${stack ? '\n' + stack : ''}`;
    })
  ),
  transports: [
    new winston.transports.Console(),
    new winston.transports.File({ filename: 'qwen-debug.log' })
  ]
});

const editor = new QwenImageEdit({
  apiKey: process.env.QWEN_API_KEY,
  debug: true,
  logger: logger,
  logRequests: true,
  logResponses: true
});

Request-Interceptor

class DebugEditor {
  constructor(options) {
    this.editor = new QwenImageEdit(options);
    this.requestLog = [];
  }
  
  async editText(options) {
    const requestId = this.generateRequestId();
    const startTime = Date.now();
    
    console.log(`🚀 [${requestId}] Starte editText-Anfrage`);
    console.log(`📝 [${requestId}] Prompt: ${options.prompt}`);
    console.log(`🖼️ [${requestId}] Bild: ${options.image}`);
    
    try {
      const result = await this.editor.editText(options);
      const duration = Date.now() - startTime;
      
      console.log(`✅ [${requestId}] Erfolgreich in ${duration}ms`);
      console.log(`💳 [${requestId}] Credits verwendet: ${result.credits}`);
      console.log(`🔗 [${requestId}] Ergebnis: ${result.imageUrl}`);
      
      this.logRequest(requestId, 'editText', options, result, duration);
      
      return result;
    } catch (error) {
      const duration = Date.now() - startTime;
      
      console.error(`❌ [${requestId}] Fehler nach ${duration}ms:`, error.message);
      console.error(`🔍 [${requestId}] Fehlercode: ${error.code}`);
      
      this.logRequest(requestId, 'editText', options, null, duration, error);
      
      throw error;
    }
  }
  
  generateRequestId() {
    return Math.random().toString(36).substring(2, 8);
  }
  
  logRequest(id, method, options, result, duration, error = null) {
    this.requestLog.push({
      id,
      method,
      options,
      result,
      duration,
      error,
      timestamp: new Date().toISOString()
    });
  }
  
  getRequestLog() {
    return this.requestLog;
  }
  
  exportDebugReport() {
    const report = {
      timestamp: new Date().toISOString(),
      totalRequests: this.requestLog.length,
      successfulRequests: this.requestLog.filter(r => !r.error).length,
      failedRequests: this.requestLog.filter(r => r.error).length,
      averageDuration: this.requestLog.reduce((sum, r) => sum + r.duration, 0) / this.requestLog.length,
      requests: this.requestLog
    };
    
    fs.writeFileSync('debug-report.json', JSON.stringify(report, null, 2));
    console.log('📊 Debug-Bericht exportiert: debug-report.json');
  }
}

// Verwendung
const debugEditor = new DebugEditor({
  apiKey: process.env.QWEN_API_KEY,
  debug: true
});

// Nach Tests
debugEditor.exportDebugReport();

Health Check

async function performHealthCheck() {
  const checks = {
    apiConnection: false,
    authentication: false,
    basicOperation: false,
    credits: false
  };
  
  console.log('🏥 Starte Gesundheitsprüfung...');
  
  try {
    // 1. API-Verbindung testen
    const response = await fetch('https://api.qwen.com/health');
    checks.apiConnection = response.ok;
    console.log(`${checks.apiConnection ? '✅' : '❌'} API-Verbindung`);
    
    // 2. Authentifizierung testen
    try {
      const status = await editor.getAccountStatus();
      checks.authentication = true;
      checks.credits = status.credits > 0;
      console.log(`✅ Authentifizierung`);
      console.log(`${checks.credits ? '✅' : '⚠️'} Credits: ${status.credits}`);
    } catch (error) {
      console.log(`❌ Authentifizierung: ${error.message}`);
    }
    
    // 3. Grundlegende Operation testen
    if (checks.authentication && checks.credits) {
      try {
        // Verwende ein kleines Test-Bild
        const testResult = await editor.analyzeImage({
          image: './test-bild-klein.jpg',
          analysisTypes: ['quality']
        });
        checks.basicOperation = true;
        console.log(`✅ Grundlegende Operation`);
      } catch (error) {
        console.log(`❌ Grundlegende Operation: ${error.message}`);
      }
    }
    
  } catch (error) {
    console.log(`❌ API-Verbindung: ${error.message}`);
  }
  
  // Zusammenfassung
  const allChecksPass = Object.values(checks).every(check => check);
  console.log('\n📋 Gesundheitsprüfung Zusammenfassung:');
  console.log(`Gesamtstatus: ${allChecksPass ? '✅ Gesund' : '❌ Probleme erkannt'}`);
  
  return checks;
}

// Regelmäßige Gesundheitsprüfung
setInterval(performHealthCheck, 5 * 60 * 1000); // Alle 5 Minuten

📞 Support kontaktieren

Wenn die oben genannten Lösungen nicht helfen, kontaktiere den Support:

Support-Kanäle

Informationen für Support-Anfragen

Füge folgende Informationen in deine Support-Anfrage ein:

// Support-Informationen sammeln
function collectSupportInfo() {
  const info = {
    // Umgebung
    nodeVersion: process.version,
    platform: process.platform,
    arch: process.arch,
    
    // Paket-Versionen
    qwenVersion: require('qwen-image-edit/package.json').version,
    
    // Konfiguration (ohne sensible Daten)
    config: {
      region: editor.config.region,
      timeout: editor.config.timeout,
      debug: editor.config.debug
    },
    
    // Letzter Fehler
    lastError: {
      code: 'EXAMPLE_ERROR',
      message: 'Beispiel-Fehlermeldung',
      timestamp: new Date().toISOString()
    },
    
    // Request-Details
    lastRequest: {
      method: 'editText',
      imageSize: '2.5MB',
      prompt: 'Beispiel-Prompt'
    }
  };
  
  console.log('📋 Support-Informationen:');
  console.log(JSON.stringify(info, null, 2));
  
  return info;
}

// Bei Problemen ausführen
collectSupportInfo();

📚 Zusätzliche Ressourcen

🚀 Erste Schritte

Schneller Einstieg in die Qwen Image Edit API

Quickstart Guide →

📖 API-Referenz

Vollständige Dokumentation aller verfügbaren Methoden

API-Referenz →

⚙️ Konfiguration

Erweiterte Konfiguration und Optimierung

Konfiguration →

💡 Beispiele

Praktische Anwendungsbeispiele und Code-Snippets

Beispiele ansehen →