---
url: https://textme-docs.matat.io/he/guide/errors.md
description: >-
  מעטפת השגיאה, סטטוס הבקשה מול סטטוס המסירה, הצלחה חלקית בכתיבות אצווה, סוגי
  הכשלים, ואילו קריאות בטוחות לניסיון חוזר.
---

# שגיאות וסטטוסים

TextMe מדווחת על כשלים בגוף של תשובת `HTTP 200` רגילה לחלוטין. יש מבנה אחד לכולם, ושדה אחד שעליו מתנים את הלוגיקה.

## מעטפת השגיאה

```json
{
  "status": 4,
  "message": "Not enough credit"
}
```

| שדה | משמעות |
|---|---|
| `status` | `0` בהצלחה; כל ערך אחר הוא כשל. |
| `message` | הסבר קריא לאדם. בסטטוס `2` הוא מציין את השדה החסר. |

::: danger אף פעם לא להתנות על סטטוס ה-HTTP לבדו
כשלי אימות, כשלי ולידציה וכשלי מכסה. כולם מגיעים כ-`HTTP 200`. לקוח שבודק רק את `response.ok` יתייחס לכל אחד מהם כאל שליחה מוצלחת.
:::

כל דוגמת קוד באתר הזה עושה את אותם שלושה צעדים: שולחת, מפענחת, ואז משווה את `status` ל-`0` לפני שהיא סומכת על כל דבר אחר בתשובה.

## שני סטטוסים, שני אוצרות מילים

המילה *סטטוס* מופיעה בשני מקומות שאינם קשורים זה לזה, ובלבול ביניהם היא טעות האינטגרציה הנפוצה ביותר.

| | איפה | אוצר המילים |
|---|---|---|
| **סטטוס הבקשה** | `status` ברמה העליונה בכל תשובה | *האם ה-API קיבל את הקריאה?*, [קודי סטטוס](../reference/status-codes.md) |
| **סטטוס המסירה** | `status` בתוך כל רשומה ב-`transactions[]` של דוח מסירה | *מה קרה להודעה במכשיר?*, [סטטוסי מסירה](../reference/dlr-statuses.md) |

דוח מסירה יכול להחזיר `status: 0` ברמה העליונה (הדוח הופק) בעוד שרשומות בודדות בתוכו נושאות `102` (נמסר) או `1` (נכשל). מדובר בשני סולמות שונים שבמקרה חולקים שם שדה.

## הצלחה חלקית {#partial-success}

כמה פעולות מקבלות אצווה ומעבדות אותה שורה-שורה. הן מחזירות `status: 0` (הפעולה רצה) יחד עם רשימת `errors` שמתארת את השורות שלא נכנסו.

```json
{
  "status": 0,
  "message": "The phone numbers have been added successfully",
  "errors": [
    "The phone 05XXXXXXXX is already on the contact list and therefore not added"
  ]
}
```

הפעולות שמתנהגות כך הן [כתיבות לרשימות תפוצה](../endpoints/contact-lists.md) (`newCL`, `removeCL`, `addNumCL`, `rmNumCL`). התייחסות ל-`status: 0` שלהן כאל "הכול עבד" תשמיט נמענים בשקט. קראו את `errors` בכל פעם שהוא קיים.

## סוגי כשלים

**פרטי גישה והרשאות**: `3`, `10`, `11`, `504`, `511`. הטוקן שגוי, פג תוקף, לא תואם, או שהחשבון אינו רשאי לבצע את הפעולה. ניסיון חוזר לא יעזור; ראו [אימות](./authentication.md).

**בקשה פגומה**: `1`, `2`, `997`. המסמך לא נפרסר, חסר שדה חובה, או שאלמנט השורש אינו פעולה. דטרמיניסטי: אותו גוף בקשה ייכשל תמיד. תקנו את הבקשה; [נקודת הקצה לבדיקות](./request-format.md#testing-without-sending) היא הדרך הזולה לעשות זאת.

**ערכים שנדחו** (`9`, `714`, `980`, `986`, `989`, `990`, `991`, `992`, `993`, `995`, `996`. שדה מסוים נכשל בוולידציה) מספר קצר מדי, הודעה ארוכה מדי, ערך `add_unsubscribe` שאינו `2` או `3`. ה-`message` מציין איזה.

**מצב החשבון**: `4` (אין יתרה), `12` (אין מספיק כסף), `5` (אין הרשאת שליחה בשעה הזו), `515` (שולח לא מאומת). אין שום בעיה בבקשה; יש בעיה בחשבון. הקריאות האלה *עשויות* להצליח בהמשך, אחרי טעינת יתרה, בשעה אחרת, או לאחר אימות השולח.

**לא נשאר למי לשלוח**: `8` (כל היעדים חסומים), `715` (כל היעדים סוננו על ידי `temp_bl`), `988` (רשימת התפוצה אינה קיימת). הקריאה הייתה תקינה ופשוט לא נשארו נמענים. כדאי לתעד את אלה בנפרד: בדרך כלל הבעיה היא בקהל, לא בקוד.

**בצד השרת**: `6`, `970`, `999`. כשל תהליך. אפשר לנסות שוב פעם אחת עם השהיה; אם זה חוזר, פנו לתמיכה.

## ניסיונות חוזרים בבטחה

אין מנגנון idempotency key. שליחה שנשלחת פעמיים היא שתי שליחות, ושתיהן יימסרו וייגבו.

* **אף פעם לא לנסות שליחה מחדש בעיוורון.** אם `sms` או `bulk` נכשלים בטיים-אאוט בשכבת התעבורה, אינכם יודעים אם ההודעה יצאה. פתרו זאת בקריאה ולא בכתיבה: תנו `id` לכל יעד (ראו [דוחות מסירה](../use-cases/delivery-reports.md)) ובדקו בדוח לפני שאתם שולחים שוב.
* **קריאות בטוחות לחזרה.** `balance`, `dlr`, `dlrByDate`, `incoming`, `getCL`, `getVerifiedPhones` ושאר פעולות הקריאה אינן משנות דבר.
* **כתיבות אינן אידמפוטנטיות.** קריאה כפולה ל-`newCL` יוצרת שתי רשימות; `addNumBL` פעמיים אינה מזיקה, אבל `updateAmountSub` פעמיים מעבירה קרדיט פעמיים.
* **השהו לפני ניסיון חוזר ב-`6` וב-`999`.** נסו שוב לאחר השהיה קצרה ולא מיד.

## דוגמה מלאה

התבנית שכל דוגמה באתר הזה משתמשת בה, במלואה:

::: code-group

```js [JavaScript]
const response = await fetch('https://my.textme.co.il/api', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.TEXTME_API_TOKEN}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify(payload),
})

// שכבת התעבורה נכשלת רק לעיתים רחוקות, אבל כשזה קורה אינכם יודעים אם
// ההודעה נשלחה. אין לנסות שליחה מחדש כאן.
if (!response.ok) {
  throw new Error(`TextMe transport error: HTTP ${response.status}`)
}

const result = await response.json()

// זו הבדיקה שקובעת.
if (Number(result.status) !== 0) {
  throw new TextMeError(result.status, result.message)
}

// פעולת אצווה יכולה להצליח בסך הכול ובכל זאת להשמיט שורות.
for (const problem of result.errors ?? []) {
  console.warn('TextMe partial failure:', problem)
}

return result
```

```python [Python]
import os

import httpx


class TextMeError(RuntimeError):
    def __init__(self, status, message):
        super().__init__(f"TextMe {status}: {message}")
        self.status = int(status)
        self.message = message


def call(payload):
    response = httpx.post(
        "https://my.textme.co.il/api",
        headers={"Authorization": f"Bearer {os.environ['TEXTME_API_TOKEN']}"},
        json=payload,
    )
    # כשל תעבורה משאיר שליחה במצב לא ידוע. אין לנסות אותה מחדש.
    response.raise_for_status()

    result = response.json()

    # זו הבדיקה שקובעת.
    if int(result["status"]) != 0:
        raise TextMeError(result["status"], result["message"])

    # פעולת אצווה יכולה להצליח בסך הכול ובכל זאת להשמיט שורות.
    for problem in result.get("errors", []):
        print("TextMe partial failure:", problem)

    return result
```

```php [PHP]
<?php

function textme(array $payload): array
{
    $client = new \GuzzleHttp\Client([
        'headers' => [
            'Authorization' => 'Bearer '.getenv('TEXTME_API_TOKEN'),
            'Accept' => 'application/json',
        ],
    ]);

    $response = $client->post('https://my.textme.co.il/api', ['json' => $payload]);
    $result = json_decode($response->getBody()->getContents(), true);

    // זו הבדיקה שקובעת.
    if ((int) $result['status'] !== 0) {
        throw new RuntimeException("TextMe {$result['status']}: {$result['message']}");
    }

    // פעולת אצווה יכולה להצליח בסך הכול ובכל זאת להשמיט שורות.
    foreach ($result['errors'] ?? [] as $problem) {
        error_log("TextMe partial failure: {$problem}");
    }

    return $result;
}
```

:::

## הטבלאות המלאות

* [קודי סטטוס](../reference/status-codes.md). כל הערכים ש-`status` ברמה העליונה יכול לקבל.
* [סטטוסי מסירה](../reference/dlr-statuses.md). כל הערכים שרשומת דוח מסירה יכולה לקבל, עם תרגום לאנגלית של ההודעות בעברית.
