Skip to content

Xatolarni Ishlash

@joyida/payme da xatolarni ishlash bo'yicha to'liq qo'llanma.

Xato Turlari

Kutubxona to'rt xil xato klassini taqdim etadi:

typescript
import {
  PaymeError,      // Payme API xatoliklari
  ValidationError, // Kiritmalarni tekshirish xatoliklari
  NetworkError,    // Tarmoq/vaqt tugashi xatoliklari
  ParseError       // JSON-RPC protokoli xatoliklari
} from '@joyida/payme';

PaymeError

Payme API tomonidan qaytarilgan xatoliklar.

Xususiyatlar

typescript
class PaymeError extends Error {
  code: number;                    // Xato kodi
  message: string;                 // Xato xabari
  data?: string | Record<string, unknown>; // Qo'shimcha ma'lumotlar
}

Misol

typescript
try {
  await payme.createTransaction(params);
} catch (error) {
  if (error instanceof PaymeError) {
    console.error('Payme xatosi:', error.code);
    console.error('Xabar:', error.message);
    console.error('Ma\'lumot:', error.data);
  }
}

Umumiy Xato Kodlari

Autentifikatsiya Xatoliklari

KodTavsifYechim
-32504Taqiqlangan (noto'g'ri maxfiy ma'lumotlar)merchantId va secretKey ni tekshiring

Tizim Xatoliklari

KodTavsifYechim
-32400Tizim xatosiKeyinroq qayta urinib ko'ring yoki qo'llab-quvvatlab bog'laning

Tranzaktsiya Xatoliklari

KodTavsifYechim
-31001Noto'g'ri sumaSummani musbat butun son ekanligini tekshiring (tiyinda)
-31003Tranzaktsiya topilmadiTranzaktsiya ID sini tasdiqlang
-31007Buyurtma bajarilgan, bekor qilib bo'lmaydiYetkazib berilgan buyurtmalarni bekor qilib bo'lmaydi
-31008Operatsiyani bajarib bo'lmaydiTranzaktsiya holatini tekshiring

Akkaunt Xatoliklari

KodTavsifYechim
-31050Akkaunt topilmadiAkkaunt tizimda mavjudligini tasdiqlang
-31051Noto'g'ri akkauntAkkaunt ma'lumotlari formatini tekshiring
-31052Akkaunt bloklanganAkkauntni blokdan chiqaring yoki qo'llab-quvvatlab bog'laning
-31053Yetarli balans yo'qAkkaunt balansini tekshiring
...Maxsus akkaunt xatoliklariBiznes mantiqingizni tekshiring
-31099Oxirgi akkaunt xato kodi-

Muayyan Xatolarni Ishlash

typescript
import { PaymeError } from '@joyida/payme';

try {
  await payme.createTransaction(params);
} catch (error) {
  if (error instanceof PaymeError) {
    switch (error.code) {
      case -32504:
        console.error('Noto\'g\'ri maxfiy ma\'lumotlar');
        // Maxfiy ma'lumotlarni yangilang
        break;

      case -31001:
        console.error('Noto\'g\'ri suma');
        // Summani tekshiring
        break;

      case -31003:
        console.error('Tranzaktsiya topilmadi');
        // Tranzaktsiya ID sini tekshiring
        break;

      case -31007:
        console.error('Bajarilgan buyurtmani bekor qilib bo\'lmaydi');
        // Foydalanuvchiga xabar bering
        break;

      case -31008:
        console.error('Noto\'g\'ri tranzaktsiya holati');
        // Operatsiyadan oldin holatni tekshiring
        break;

      case -31050:
        console.error('Akkaunt topilmadi');
        // Akkaunt mavjudligini tasdiqlang
        break;

      default:
        console.error('Noma\'lum xato:', error.code);
    }
  }
}

ValidationError

Kiritmalarni tekshirish xatoliklari (API chaqiruvidan oldin).

Xususiyatlar

typescript
class ValidationError extends Error {
  message: string; // Tekshirish xato xabari
}

Misol

typescript
import { ValidationError } from '@joyida/payme';

try {
  await payme.createTransaction({
    id: 'noto\'g\'ri', // juda qisqa
    time: Date.now(),
    amount: -100, // manfiy
    account: {}
  });
} catch (error) {
  if (error instanceof ValidationError) {
    console.error('Tekshirish xatosi:', error.message);
    // Foydalanuvchiga xabar ko'rsating
  }
}

Umumiy Tekshirish Xatoliklari

XatoTavsif
"Amount must be a positive integer"Suma manfiy yoki butun son emas
"Card number must be 13-19 digits"Karta raqami uzunligi noto'g'ri
"Invalid card expiry format"Amal qilish muddati MMYY formatida emas
"Card has expired"Amal qilish muddati o'tgan
"Invalid phone number format"Telefon 998XXXXXXXXX formatida emas
"Payme ID must be 24 characters"Tranzaktsiya ID uzunligi noto'g'ri
"Timestamp must be 13 digits"Unix timestamp noto'g'ri
"Account must be a non-empty object"Bo'sh akkaunt obyekti
"Token must be a non-empty string"Bo'sh token

Validatsiya Xatoliklarini Oldini Olish

typescript
import { Validator } from '@joyida/payme';

// API chaqiruvidan oldin tekshirish
try {
  Validator.validateAmount(500000);
  Validator.validateCardNumber('8600069195406311');
  Validator.validateCardExpiry('0399');
  Validator.validatePhone('998901234567');
  Validator.validatePaymeId('5305e3bab097f420a62ced0b');
  Validator.validateTimestamp(Date.now());
  Validator.validateAccount({ order_id: '123' });
  Validator.validateToken('card_token_here');

  // Hammasi to'g'ri, API chaqiruvi bilan davom eting
  await payme.createTransaction(params);
} catch (error) {
  if (error instanceof ValidationError) {
    console.error('Tekshirish muvaffaqiyatsiz:', error.message);
  }
}

NetworkError

Tarmoq yoki vaqt tugashi xatoliklari.

Xususiyatlar

typescript
class NetworkError extends Error {
  message: string;      // Xato xabari
  timeout?: number;     // Vaqt tugashi qiymati (agar vaqt tugashi xatosi bo'lsa)
  cause?: unknown;      // Asl xato
}

Misol

typescript
import { NetworkError } from '@joyida/payme';

try {
  await payme.createTransaction(params);
} catch (error) {
  if (error instanceof NetworkError) {
    console.error('Tarmoq xatosi:', error.message);

    if (error.timeout) {
      console.error(`So'rov ${error.timeout}ms dan keyin vaqt tugadi`);
      // Uzoqroq vaqt tugashi bilan qayta urinib ko'ring
    }
  }
}

Tarmoq Xatoliklarini Ishlash

typescript
async function createTransactionWithRetry(
  params: CreateTransactionParams,
  maxRetries = 3
) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      return await payme.createTransaction(params);
    } catch (error) {
      if (error instanceof NetworkError) {
        console.log(`Qayta urinish ${i + 1}/${maxRetries}`);

        if (i === maxRetries - 1) {
          throw error; // Oxirgi urinish muvaffaqiyatsiz
        }

        // Qayta urinishdan oldin kutish (exponential backoff)
        await new Promise(resolve =>
          setTimeout(resolve, Math.pow(2, i) * 1000)
        );
      } else {
        throw error; // Tarmoq xatosi emas, qayta urinmayman
      }
    }
  }
}

ParseError

JSON-RPC protokoli xatoliklari.

Xususiyatlar

typescript
class ParseError extends Error {
  message: string; // Parser xato xabari
}

Misol

typescript
import { ParseError } from '@joyida/payme';

try {
  await payme.createTransaction(params);
} catch (error) {
  if (error instanceof ParseError) {
    console.error('Protokol xatosi:', error.message);
    // Bu odatda buzilish yoki API o'zgarishini ko'rsatadi
  }
}

To'liq Xato Ishlash Misoli

typescript
import {
  PaymeMerchant,
  PaymeError,
  ValidationError,
  NetworkError,
  ParseError
} from '@joyida/payme';

const payme = new PaymeMerchant({
  merchantId: process.env.PAYME_MERCHANT_ID!,
  secretKey: process.env.PAYME_SECRET_KEY!,
});

async function processPayment(orderId: string, amount: number) {
  try {
    // Tranzaktsiya yaratish
    const result = await payme.createTransaction({
      id: generatePaymeId(),
      time: Date.now(),
      amount,
      account: { order_id: orderId }
    });

    console.log('✅ Tranzaktsiya yaratildi:', result.transaction);
    return result;

  } catch (error) {
    // Turli xato turlarini ishlash
    if (error instanceof ValidationError) {
      // Kiritma tekshirish xatosi
      console.error('❌ Tekshirish xatosi:', error.message);
      throw new Error(`Noto'g'ri kiritma: ${error.message}`);

    } else if (error instanceof PaymeError) {
      // Payme API xatosi
      console.error('❌ Payme xatosi:', error.code, error.message);

      switch (error.code) {
        case -32504:
          throw new Error('To\'lov tizimi sozlamalari xatosi');

        case -31001:
          throw new Error('Noto\'g\'ri to\'lov summasi');

        case -31003:
          throw new Error('Tranzaktsiya topilmadi');

        case -31007:
          throw new Error('Bajarilgan buyurtmani bekor qilib bo\'lmaydi');

        case -31008:
          throw new Error('Noto\'g\'ri tranzaktsiya holati');

        case -31050:
          throw new Error('Buyurtma topilmadi');

        case -32400:
          throw new Error('To\'lov tizimi vaqtinchalik mavjud emas');

        default:
          throw new Error(`To'lov xatosi: ${error.message}`);
      }

    } else if (error instanceof NetworkError) {
      // Tarmoq yoki vaqt tugashi xatosi
      console.error('❌ Tarmoq xatosi:', error.message);

      if (error.timeout) {
        throw new Error(`So'rov ${error.timeout}ms dan keyin vaqt tugadi`);
      } else {
        throw new Error('Tarmoq aloqa xatosi');
      }

    } else if (error instanceof ParseError) {
      // Protokol xatosi
      console.error('❌ Protokol xatosi:', error.message);
      throw new Error('To\'lov tizimi protokol xatosi');

    } else {
      // Noma'lum xato
      console.error('❌ Noma'lum xato:', error);
      throw new Error('Kutilmagan xato yuz berdi');
    }
  }
}

Xato Jurnalini Yuritish

Oddiy Jurnal

typescript
import { PaymeError } from '@joyida/payme';

try {
  await payme.createTransaction(params);
} catch (error) {
  if (error instanceof PaymeError) {
    // Konsolga yozish
    console.error({
      timestamp: new Date().toISOString(),
      type: 'PaymeError',
      code: error.code,
      message: error.message,
      data: error.data
    });
  }
}

Advans Jurnal

typescript
import { PaymeError, ValidationError, NetworkError } from '@joyida/payme';

function logError(error: unknown, context: Record<string, unknown>) {
  const logEntry = {
    timestamp: new Date().toISOString(),
    context,
    error: {
      type: error.constructor.name,
      message: error.message
    }
  };

  if (error instanceof PaymeError) {
    logEntry.error = {
      ...logEntry.error,
      code: error.code,
      data: error.data
    };
  } else if (error instanceof NetworkError) {
    logEntry.error = {
      ...logEntry.error,
      timeout: error.timeout
    };
  }

  // Jurnal xizmatiga yuborish
  console.error(JSON.stringify(logEntry));
}

// Foydalanish
try {
  await payme.createTransaction(params);
} catch (error) {
  logError(error, {
    operation: 'createTransaction',
    orderId: params.account.order_id,
    amount: params.amount
  });
  throw error;
}

Eng Yaxshi Amaliyotlar

✅ Kerakli ishlar

  1. Xatolarni doimo tuting va ishlang
  2. Turli xil ishlash uchun muayyan xato turlaridan foydalaning
  3. Xatolarni kontekst bilan jurnalga yozing
  4. Foydalanuvchiga qulay xabarlarni ko'rsating
  5. Tarmoq xatoliklari uchun qayta urinish mantiqini implementatsiya qiling
  6. API chaqiruvlaridan oldin kiritmalarni tekshiring
  7. Xato stavkalarini kuzating

❌ Kerakli emaslar

  1. Xatolarni e'tiborsiz qoldirmang
  2. Xato xabarlarida maxfiy ma'lumotlarni oshkor qilmang
  3. Validatsiya xatoliklarida qayta urinmang
  4. Foydalanuvchilarga texnik xatolarni ko'rsatmang
  5. Cheksiz qayta urinmang
  6. Maxfiy ma'lumotlarni jurnalga yozmang (karta raqamlari, tokenlar)

Xatolarni Kuzatish

Sentry Integratsiyasi

typescript
import * as Sentry from '@sentry/node';
import { PaymeError } from '@joyida/payme';

try {
  await payme.createTransaction(params);
} catch (error) {
  if (error instanceof PaymeError) {
    Sentry.captureException(error, {
      tags: {
        error_code: error.code,
        error_type: 'PaymeError'
      },
      extra: {
        data: error.data
      }
    });
  }
  throw error;
}

Keyingi Qadamlar

MIT Lizenziyasi ostida chiqarilgan.