דילוג לתוכן
תיעוד Nodaro
תיעודמדריך הרכיביםמודליםתבניותסוכני AI (MCP)מפתחיםאירוח עצמימחקרהשוואות
SDK ל-TypeScript

שגיאות

כל שגיאה שה-SDK של Nodaro ל-TypeScript זורק: סטטוס ה-HTTP, הקוד והשדות, ומה עושים במחסור בקרדיטים, במגבלות קצב, בהתנגשויות ובמשימות שנכשלו.

כל שגיאה שה-SDK של Nodaro זורק בעקבות תשובה של ה-API היא מופע של NodaroError או של אחת מתת־המחלקות שלה. בקשה שנכשלת עם סטטוס שגיאה זורקת את תת־המחלקה שמתאימה לסטטוס. פונקציות העזר שמריצות וממתינות זורקות תת־מחלקות משלהן כשמשימה נכשלת, חורגת מהזמן או נעצרת. תפסו קודם את המחלקות הספציפיות, ואת NodaroError בסוף.

כל מחלקות השגיאה

מחלקהסטטוסcodeשדות נוספיםמתי היא נזרקת
NodaroErrorכל סטטוסהקוד של השרתמחלקת הבסיס, וכל שגיאה שאין לה מחלקה ספציפית יותר
UnauthorizedError401unauthorizedהאסימון חסר, פג תוקפו או לא תקין
ForbiddenError403forbiddenmissingScope?הגישה נדחתה, או שלאסימון OAuth חסרה הרשאה
ModelUnavailableError403model_not_available או model_disabledהמודל שבחרתם לא מוצע, או שמנהל כיבה אותו
ImportRefusedError403imports_blocked, import_source_disabled או קוד rights_*ייבוא של קישור נדחה עוד לפני שהתוכן נמשך
NotFoundError404not_foundהפריט לא קיים, או שאין לכם גישה אליו
RateLimitedError429rate_limitedיותר מדי בקשות
InsufficientCreditsError402insufficient_credits או קוד 402 אחרrequired?, available?החשבון לא יכול לשלם על ההרצה
CreditCapExceededError402budget_exceeded, member_cap_exceeded או user_allowance_exceededrequired?, available?ההרצה חורגת מתקרת הוצאה שמישהו אחר קבע
StorageExceededError413storage_exceededlimitBytes?, reason?מה ששלחתם לא נכנס: האחסון מלא, או שקובץ אחד חורג מהמגבלה
WorkflowConflictError409workflow_conflict או production_busycurrentUpdatedAt?, currentVersion?, currentRecord?מישהו אחר שינה את הפריט לפניכם
AlreadyRunningError409already_runningexecutionIdההרצה שביקשתם להתחיל או להמשיך עדיין רצה
AppRunVersionChangedError409app_run_version_changedrunVersion?, appVersion?ניסיון חוזר של הרצת אפליקציה נדחה, כי האפליקציה עברה לגרסה אחרת
JobBlockedError422job_blockedמדיניות התוכן של הפריסה דחתה את הבקשה
StudioOpError4xxהקוד של השרתopIndexפעולה אחת באצווה של Studio נדחתה
JobFailedError0job_failedjobId, jobStatusמשימה שחיכיתם לה נכשלה או בוטלה
JobTimeoutError0job_timeoutjobId, timeoutMsמשימה לא הסתיימה בתוך maxMs
JobAbortedError0job_abortedjobId?ההמתנה בוטלה דרך ה-AbortSignal שלכם
JobHeldError0job_heldjobIdמשימה ממתינה לבדיקה של אדם
StudioPreviewUnavailable0studio_preview_unavailableהפריסה לא יכולה להציג תצוגה מקדימה של אצווה של Studio
StudioPreviewAppliedError0studio_preview_appliedappliedאצווה של Studio שביקשתם לראות בתצוגה מקדימה הוחלה בפועל

לכל מחלקה יש ארבעה שדות: message, משפט קריא; code, מחרוזת קבועה שאפשר להשוות אליה; status, סטטוס ה-HTTP; ו-details. הערך 0 ב-status פירושו שהשגיאה לא הגיעה מתשובת HTTP. למשל, את JobTimeoutError זורקת לולאת התשאול של ה-SDK עצמו.

ב-details נמצאים כל השדות של מעטפת השגיאה מלבד code ו-message, כפי שהשרת שלח אותם. למשל, slot כשטרנד נדחה, reasons כשפרסום נדחה ו-issues כשהקלט לא תקין. הערך הוא {} כשלא היה במעטפת שום דבר נוסף, וגם בשגיאה שה-SDK יצר בעצמו.

try {
  await client.trends.run(slug, request)
} catch (err) {
  if (err instanceof NodaroError && err.code === "missing_slot") askFor(err.details.slot as string)
}

הבנאי הוא new NodaroError(message, code, status, details?).

חלק מהסטטוסים ממופים למחלקה אחת, בלי קשר לקוד שהשרת שלח. שגיאת 403 הופכת ל-ForbiddenError עם code בערך forbidden, חוץ מדחייה של מודל, שהופכת ל-ModelUnavailableError, ומדחייה של ייבוא קישור, שהופכת ל-ImportRefusedError. שגיאת 404 הופכת ל-NotFoundError, וכל שגיאת 413 הופכת ל-StorageExceededError. במקרים האלה, את הסיבה של השרת קוראים ב-message. שגיאת 409 הופכת ל-WorkflowConflictError רק עם הקוד workflow_conflict או production_busy. שגיאת 409 עם already_running שמציינת executionId הופכת ל-AlreadyRunningError, ושגיאת 409 עם app_run_version_changed הופכת ל-AppRunVersionChangedError. שגיאות עם כל סטטוס אחר, כגון 400 או 503, ושגיאת 409 עם כל קוד אחר, מגיעות כ-NodaroError עם ה-code של השרת עצמו.

תפיסת שגיאות לפי הסדר

import {
  ForbiddenError,
  InsufficientCreditsError,
  ModelUnavailableError,
  NodaroError,
  NotFoundError,
  RateLimitedError,
  StorageExceededError,
  UnauthorizedError,
} from "@nodaro/sdk"

try {
  await client.workflows.run(workflowId)
} catch (err) {
  if (err instanceof UnauthorizedError) {
    redirectToLogin()
  } else if (err instanceof ModelUnavailableError) {
    showError("This model is not available. Choose another model.")
  } else if (err instanceof ForbiddenError) {
    if (err.missingScope) requestAdditionalScopes([err.missingScope])
    else showError("You do not have permission to do this.")
  } else if (err instanceof InsufficientCreditsError) {
    showCreditPaywall({ required: err.required, available: err.available })
  } else if (err instanceof RateLimitedError) {
    await retryWithBackoff()
  } else if (err instanceof StorageExceededError) {
    if (err.reason === "file_too_large") showError("This file is too large.")
    else showError(`Storage limit of ${err.limitBytes} bytes reached.`)
  } else if (err instanceof NotFoundError) {
    showError("Not found.")
  } else if (err instanceof NodaroError) {
    console.error(`API error ${err.status} (${err.code}): ${err.message}`)
  } else {
    throw err // a network failure or a timeout, not an API answer
  }
}

כשבקשה חורגת מ-timeoutMs של הלקוח, או כשיש כשל רשת, ה-Promise נדחה עם שגיאה של סביבת הריצה עצמה, כגון AbortError או TypeError. השגיאות האלה הן לא מופעים של NodaroError.

אימות והרשאות

UnauthorizedError

HTTP 401. האסימון חסר, פג תוקפו או לא תקין. קבלו אסימון חדש, או בקשו מהמשתמש להתחבר שוב, ואז נסו שוב.

ForbiddenError

HTTP 403. למי שקרא אין הרשאה לפעולה הזו. כשאסימון OAuth לא קיבל הרשאה שנקודת הקצה דורשת, השדה missingScope מציין את ההרשאה הזו, למשל workflows:execute. בקשו מהמשתמש לאשר אותה, ואז נסו שוב עם האסימון החדש. ראו את הסעיף הרשאות (scopes) והרשאות חסרות בדף אימות.

סיבות אחרות הן, למשל, מהדורה שלא כוללת את היכולת או תפקיד נמוך מדי. כולן מגיעות עם code בערך forbidden, ולכן הציגו את message כדי להסביר מה הסיבה.

ModelUnavailableError

HTTP 403 שדוחה את המודל, ולא את מי שקרא. Nodaro עונה כך עוד לפני שמשוריינים קרדיטים. בחרו מודל אחר: ניסיון חוזר, טעינת קרדיטים או הרשאה רחבה יותר לא ישנו כלום.

codeסיבת הדחייה
model_not_availableהפריסה הזו לא מציעה את המודל. המודל לא כלול במהדורה או בממשק שלה, או שמנהל השרת הסתיר אותו.
model_disabledמנהל כיבה את המודל.

המחלקה ModelUnavailableError מרחיבה את ForbiddenError, ולכן בדיקת instanceof ForbiddenError שכבר יש בקוד שלכם עדיין תופסת אותה. כדי להבחין בין השתיים, בדקו קודם instanceof ModelUnavailableError. השתמשו ב-code כדי להציג משפט משלכם, ולא ב-message באנגלית. הקבוע MODEL_UNAVAILABLE_CODES, מטיפוס ReadonlySet<ModelUnavailableCode>, מפרט את שני הקודים. השגיאה לא מציינת את המודל: המודל שנדחה הוא ה-provider של הבקשה שלכם, או אחד מה-models שלה, כשהבקשה מריצה כמה מודלים. שגיאת 403 עם insufficient_scope, עם כל קוד אחר או בלי קוד נשארת ForbiddenError רגילה.

הבנאי הוא new ModelUnavailableError(code, message?). הבנאי של ForbiddenError הוא new ForbiddenError(message?, missingScope?, code?).

ImportRefusedError

HTTP 403 שדוחה ייבוא של קישור, עוד לפני שהתוכן נמשך: media.downloadVideo(), uploads.importUrl() וייבואי האודיו. הסירוב הגיע מאמצעי שהוחל על החשבון, מבדיקת זכויות התוכן או ממדיניות האתרים של הפריסה. ראו את דף ה-API זכויות תוכן ואת הסעיף מפרים חוזרים באותו דף.

codeסיבת הדחייה
imports_blockedייבוא קישורים חסום בחשבון, או שהחשבון סגור, לפי מדיניות המפרים החוזרים של הפריסה. ההודעה מציינת עד מתי: תאריך לפי UTC, או עד שמנהל יסיר את החסימה.
import_source_disabledהפריסה לא מאפשרת ייבוא מהאתר של הקישור. ההודעה לא מציינת שום אתר.
rights_confirmation_requiredהפריסה דורשת אישור, ולא נשלח אישור.
rights_authorization_requiredהפריסה דורשת אישור, הייבוא הגיע דרך מפתח API, אפליקציה מחוברת או סוכן AI, ולחשבון אין הרשאה קבועה. בעל החשבון נותן את ההרשאה מתוך הסשן שלו, עם contentRights.authorize().
rights_confirmation_not_foundאין אישור עם המזהה הזה.
rights_confirmation_mismatchהאישור שייך לקישור אחר או לחשבון אחר.
rights_confirmation_staleההצהרה השתנתה. טענו אותה שוב ואשרו שוב.
rights_confirmation_expiredהאישור ישן יותר משעה.
rights_confirmation_usedהאישור כבר נוצל לייבוא. גם ייבוא שנכשל אחרי שמשיכת התוכן התחילה מנצל את האישור.

כשהקוד הוא rights_confirmation_*, קראו שוב ל-client.contentRights.confirm({ url, declarationVersion }) וייבאו שוב עם המזהה החדש. המחלקה ImportRefusedError מרחיבה את ForbiddenError, ולכן בדיקת instanceof ForbiddenError שכבר יש בקוד שלכם עדיין תופסת אותה. בדקו קודם instanceof ImportRefusedError, והשתמשו ב-code כדי להציג משפט משלכם. הקבוע IMPORT_REFUSAL_CODES, מטיפוס ReadonlySet<ImportRefusalCode>, מפרט את הקודים. הבנאי הוא new ImportRefusedError(code, message?).

NotFoundError

HTTP 404. הפריט לא קיים, או שמי שקרא לא יכול לראות אותו. Nodaro עונה באותה דרך בשני המקרים, ולכן מזהה אף פעם לא מגלה אם קיים משהו שאין לכם גישה אליו. משאב שקיים רק ב-Nodaro Cloud, כגון הפקות Studio או Recast, מחזיר 404 גם בהתקנה באירוח עצמי.

קרדיטים, אחסון ומגבלות

InsufficientCreditsError

HTTP 402. החשבון לא יכול לשלם על ההרצה, ולכן שום דבר לא התחיל. השדה required הוא מספר הקרדיטים שההרצה צריכה, והשדה available הוא מספר הקרדיטים שיש בחשבון, או, כשמדובר בתקרה, מה שנשאר בה. Nodaro Cloud ממלא את שניהם, אבל הטיפוס מסמן אותם כאופציונליים. השדה code הוא הקוד של הדחייה עצמה: הקוד insufficient_credits כשהבעיה היא היתרה שלכם וגם כשהשרת לא שלח קוד, ואחרת קוד 402 אחר, כגון free_video_limit או insufficient_app_credits.

try {
  await client.nodes.runAndWait("generate-video", params)
} catch (err) {
  if (err instanceof InsufficientCreditsError) {
    console.log(`Need ${err.required} credits, have ${err.available}`)
  }
}

בדקו את היתרה לפני הרצה עם client.credits.balance(). ראו את הדף קרדיטים.

CreditCapExceededError

HTTP 402 בגלל תקרת הוצאה שמישהו אחר קבע, ולא בגלל היתרה שלכם. טעינת קרדיטים לא תעזור: מי שקבע את התקרה צריך להגדיל אותה.

codeהתקרה
budget_exceededהתקציב של סביבת העבודה
member_cap_exceededתקרת הקרדיטים שלכם בסביבת העבודה הזו
user_allowance_exceededהמכסה של הפריסה לכל משתמש

המחלקה CreditCapExceededError מרחיבה את InsufficientCreditsError, ולכן בדיקת instanceof InsufficientCreditsError שכבר יש בקוד שלכם עדיין תופסת אותה. כדי להבחין בין השתיים, בדקו קודם instanceof CreditCapExceededError. הקבוע CREDIT_CAP_CODES, מטיפוס ReadonlySet<CreditCapCode>, מפרט את שלושת הקודים.

StorageExceededError

HTTP 413. מה ששלחתם לא נכנס. כל שגיאת 413 מגיעה כמחלקה הזו, בכל נתיב, והשדה reason מציין באיזה סוג מדובר:

reasonמשמעות
storage_limit_exceededהאחסון של החשבון מלא. השדה limitBytes הוא המגבלה. מחקו מדיה שאתם כבר לא צריכים, ואז נסו שוב.
file_too_largeקובץ אחד חורג ממגבלת הגודל. האחסון לא מלא. שלחו קובץ קטן יותר.
payload_too_large, post_too_large, duration_exceededהבקשה, הפוסט או אורך המדיה חורגים ממגבלה. האחסון לא מלא.

כשבתשובה לא היה קוד, השדה reason הוא undefined. העלאות והעתקות לאחסון שלכם, כגון שכפול מספריית הקהילה, זורקות את השגיאה הזו. הבנאי הוא new StorageExceededError(message?, limitBytes?, reason?).

RateLimitedError

HTTP 429. שלחתם יותר מדי בקשות. המתינו, ואז נסו שוב עם המתנה שהולכת ומתארכת: למשל 2 שניות, אחר כך 4 ואחר כך 8. הפסיקו אחרי כמה ניסיונות. ראו את דף ה-API מגבלות קצב.

המתנה למשימות

המתודות client.nodes.runAndWait() ו-client.nodes.runMany(), ופונקציות העזר ...AndWait של משאבים אחרים בודקות את הסטטוס של משימה מדי כמה שניות, עד שהיא מסתיימת. בזמן ההמתנה הן זורקות את השגיאות האלה.

JobFailedError

המשימה הסתיימה בסטטוס failed או cancelled. השדה jobStatus מציין איזה מהשניים, השדה jobId מזהה את המשימה, והשדה message כולל את הודעת השגיאה של המשימה עצמה. קבלו את המשימה המלאה עם client.jobs.get(err.jobId): השדה error_hint שלה מסביר חסימה של מסנן בטיחות או של מדיניות.

JobTimeoutError

המשימה לא הגיעה לסטטוס סופי בתוך maxMs, שהוא 15 דקות כברירת מחדל. המשימה לא מבוטלת. בדרך כלל היא בכל זאת מסתיימת בשרת ונשמרת בספרייה שלכם. בדקו אותה מאוחר יותר עם client.jobs.get(err.jobId), או העבירו maxMs גדול יותר למודלים איטיים. משימה שנמצאת בהתאוששות מדווחת recovering: true בסטטוס שלה, וההתאוששות יכולה לקחת עשרות דקות.

JobAbortedError

ההמתנה בוטלה דרך ה-AbortSignal שלכם. ה-SDK מפסיק מיד לבדוק את הסטטוס. המשימה לא מבוטלת. כדי לעצור אותה בשרת ולקבל החזר על הקרדיטים ששוריינו לה, קראו ל-client.jobs.cancel(err.jobId).

JobHeldError

המשימה הגיעה לסטטוס pending_review: מדיניות תוכן של הפריסה הזו מעכבת את התוצאה עד שאדם יבדוק אותה. ה-SDK מפסיק לחכות כבר בפעם הראשונה שהוא רואה את הסטטוס הזה. המשימה לא מבוטלת, והקרדיטים שלה נשארים משוריינים במהלך הבדיקה. אל תריצו את הבקשה שוב, כי גם בקשה כפולה תמתין לבדיקה.

בדקו את המשימה מאוחר יותר עם client.jobs.get(err.jobId). היא מסתיימת בסטטוס completed כשהבודק מאשר אותה, בסטטוס failed כשהבודק דוחה אותה, או בסטטוס cancelled אם תבטלו אותה. במשימה שנדחתה יש error_hint.kind בערך policy-block, ו-reason שאפשר להציג כמו שהוא. השגיאה הזו קורית רק בפריסות שרושמות מדיניות משימות.

JobBlockedError

HTTP 422 עם הקוד job_blocked. מדיניות תוכן של הפריסה הזו דחתה את הבקשה לפני שהיא רצה. לא נוצרה משימה ולא נגבו קרדיטים. השדה message נכתב בשביל המשתמשים שלכם, ולכן הציגו אותו כמו שהוא. אל תנסו שוב את אותה בקשה. השגיאה הזו קורית רק בפריסות שרושמות מדיניות משימות.

שינויים מקבילים

WorkflowConflictError

HTTP 409. שלחתם שינוי מותנה, ומישהו אחר שינה את הפריט לפניכם. השגיאה מגיעה עם אחד משני קודים:

  • הקוד workflow_conflict: קריאה ל-client.workflows.update() עם expectedVersion או expectedUpdatedAt לא תאמה לתהליך השמור.
  • הקוד production_busy: הפקת Studio המשיכה להשתנות בזמן שהשרת החיל את השינוי שלכם, והשרת הפסיק לנסות שוב.

הפתרון זהה בשני המקרים: טענו את הפריט מחדש, החילו את השינוי שלכם על העותק העדכני ושלחו אותו שוב. כשהשרת מצרף אותו, ב-currentRecord נמצא התהליך הנוכחי, ולכן אפשר למזג בלי לטעון אותו שוב.

import { WorkflowConflictError } from "@nodaro/sdk"

try {
  await client.workflows.update(id, { settings, expectedVersion: loadedVersion })
} catch (err) {
  if (err instanceof WorkflowConflictError && err.currentRecord) {
    const merged = mergeSettings(err.currentRecord.settings, settings)
    await client.workflows.update(id, { settings: merged, expectedVersion: err.currentVersion })
  } else {
    throw err
  }
}

AlreadyRunningError

HTTP 409 עם הקוד already_running. ההרצה שביקשתם להתחיל או להמשיך עדיין רצה, והשדה executionId מזהה אותה. במקום להתחיל אותה שוב, בדקו את המצב שלה עם client.executions.get(executionId). המתודה client.workflows.run() זורקת את השגיאה הזו כשהרצה של התהליך כבר בעיצומה. המתודה client.apps.resume() זורקת אותה כשניסיון חוזר של ההרצה ממתין.

המחלקה הזו נבחרת כששגיאת ה-409 כוללת executionId. שגיאת 409 שלא מציינת אף הרצה נשארת NodaroError רגילה.

AppRunVersionChangedError

HTTP 409 עם הקוד app_run_version_changed. ניסיון חוזר של הרצת אפליקציה שנכשלה, עם client.apps.resume(), נדחה, כי האפליקציה נמצאת בגרסה אחרת מזו שההרצה הריצה. שום דבר לא נכתב, ולא נגבו קרדיטים.

  • השדה runVersion: הגרסה שההרצה הריצה.
  • השדה appVersion: הגרסה שאתם נמצאים בה, כלומר ה-version ששלחתם, או, אם לא שלחתם, הגרסה האחרונה של האפליקציה.

כשהתשובה לא כוללת אותם, שני השדות הם undefined. כדי להריץ את הגרסה הנוכחית של האפליקציה, התחילו את ההרצה מחדש עם client.apps.run(). כדי להמשיך בגרסה של ההרצה עצמה, קראו שוב ל-resume עם { version: err.runVersion }.

מיקומים ואובייקטים משתמשים בקוד התנגשות משלהם, concurrent_modification, שמגיע כ-NodaroError רגילה. טפלו בו באותה דרך: טענו את הפריט מחדש, מזגו ונסו שוב.

אצוות של Studio

שלוש המחלקות האלה שייכות למתודות של הפקות Studio.

  • StudioOpError: אצווה של פעולות נדחתה, והשדה opIndex הוא המיקום של הפעולה שגרמה לכך, כשהספירה מתחילה מ-0. שום דבר מהאצווה לא נכתב. תקנו את הפעולה הזו ושלחו שוב את כל האצווה.
  • StudioPreviewUnavailable: ביקשתם תצוגה מקדימה עם dryRun: true, והפריסה הזו לא יכולה לתת אותה. האצווה שלכם לא נשלחה. אמרו למשתמש שתצוגה מקדימה לא זמינה, ואל תחילו את האצווה בלי לשאול אותו.
  • StudioPreviewAppliedError: ביקשתם תצוגה מקדימה, והאצווה הוחלה בכל זאת. התייחסו ל-applied.production ול-applied.version כמצב הנוכחי. אל תשלחו את האצווה שוב. כש-applied הוא undefined, טענו את ההפקה מחדש לפני שאתם מחליטים משהו.

קודים שעשויים להגיע ב-NodaroError

הקודים האלה מגיעים ב-NodaroError רגילה. כדי לטפל בהם, השוו את err.code.

סטטוסקודאיפהמשמעות
400validation_errorמתודות רבותשדה חסר או לא תקין. השדה message מציין איזה שדה.
400no_valid_inputsclient.reduce.run()כל הקלטים היו ריקים.
400invalid_edlclient.edit.applyEdl()רשימת העריכה לא עברה את בדיקת התקינות.
400limit_reachedclient.developerApps.create()כבר הגעתם למספר המרבי של יישומי מפתחים.
400locked_fieldclient.apps.run()דריסה ניסתה לשנות יעד, כגון כתובת Webhook.
409name_takenדמויות, ארגוניםהשם או ה-slug כבר תפוסים.
409concurrent_modificationמיקומים, אובייקטיםהפריט השתנה מאז שטענתם אותו.
410voice_cloning_retiredclient.voices.createClone()שכפול קול כבר לא מוצע. במקום זאת, עצבו קול.
400quote_unsupportedclient.nodes.quote()הפלטפורמה לא יכולה לתת אומדן מחיר לסוג הרכיב הזה. ההודעה מפרטת את הסוגים שאפשר לקבל עליהם אומדן מחיר.
400, 502advanced_mode_unavailableclient.llm.structured()הספק של המודל עצמו לא יכול לקבל כרגע בקשות במצב מתקדם. כבו את המצב המתקדם כדי להריץ את המודל.
409job_cancelledבקשות LLM שמחויבות לפי השימוש, כגון client.llm.structured()המשימה בוטלה אחרי שהקרדיטים שלה שוריינו, אבל לפני שהקריאה שלה נשלחה. לא נגבים קרדיטים. אל תנסו אותה שוב כמו שהיא: המשימה בוטלה בכוונה.
503job_start_failedבקשות LLM שמחויבות לפי השימושהשרת לא הצליח לרשום שהקריאה מתחילה, ולכן הוא לא שלח אותה. לא נגבים קרדיטים. נסו שוב.
503provider_unavailableclient.llm.structuredJob()המופע לא יכול להריץ את המודל הזה. אל תנסו שוב.
503feature_disabledclient.copilotהיכולת כבויה בפריסה הזו.
503nodaro_connection_requiredclient.edit.editPlan()התקנה באירוח עצמי צריכה לשם כך חיבור ל-Nodaro Cloud.

כל דף במדריך מפרט את הקודים של המתודות שלו. דף ה-API שגיאות מפרט כל קוד שה-API יכול לשלוח.

ניסיון חוזר בבטחה

  • נסו שוב בקשות קריאה בלי חשש. ל-get או ל-list אין תופעות לוואי.
  • אל תחזרו על בקשה בתשלום בלי לבדוק. ייתכן שבקשה שחרגה מפסק הזמן כבר התחילה הרצה. לפני שאתם מנסים שוב יצירה, העבירו מפתח אידמפוטנטיות: המתודות client.nodes.run(type, params, { idempotencyKey }) ו-runAndWait מקבלות מפתח כזה. כשאתם מנסים שוב את אותה בקשה, שלחו שוב את אותו מפתח, והפלטפורמה תחזיר את ההרצה הראשונה במקום להתחיל הרצה שנייה ולגבות עליה קרדיטים.
  • Studio ו-Recast משתמשים באסימוני ניסיון חוזר משלהם: הפרמטר clientRequestId במתודות של Studio והפרמטר requestId ב-client.recast.rescore().
  • נסו שוב אחרי תשובות 5xx, עם הפסקה. פונקציית fetch משלכם ב-createClient היא מקום טוב ללוגיקה הזו.

throwFromResponse(status, body)‎

throwFromResponse(status: number, body: {
  error?: { code?: string; message?: string; [key: string]: unknown }
}): never

ממפה סטטוס HTTP וגוף שגיאה של Nodaro למחלקת השגיאה המתאימה, וזורקת אותה. ה-SDK משתמש בה בכל תגובה, והיא מיוצאת בשביל מימושי תעבורה משלכם שקוראים ל-API בלי הלקוח.

מאפיין

סוג

import { throwFromResponse } from "@nodaro/sdk"

throwFromResponse(403, {
  error: { code: "insufficient_scope", message: "Missing scope", missingScope: "workflows:execute" },
})
// throws a ForbiddenError whose missingScope is "workflows:execute"

רוב הנתיבים עונים עם המעטפת { error: { code, message } }. כמה נתיבים ישנים יותר עונים במבנים אחרים, וה-SDK מפענח גם אותם, כך שגם בשגיאות שלהם יש code ו-message אמיתיים:

גוףcodemessage
{ error: "<code>", message? }, למשל מאימון דמויותהמחרוזתmessage, או הקוד כשאין message
{ error: "<code>", error_description }, מ-OAuthהמחרוזתerror_description
{ message, issues: [...] }, תשובה על קלט לא תקין עם HTTP 400validation_errormessage
{ statusCode, error: "<reason phrase>", message }, למשל נתיב שלא קיים בשרתinternal_errormessage

ב-HTTP 500 ומעלה, ה-SDK לוקח מהמבנים האלה רק את הקוד, אף פעם לא את הטקסט. השדה message של שגיאה כזו הוא הקוד שלה, או "Request failed" (הבקשה נכשלה). השדה message של המעטפת עצמה נלקח בכל סטטוס.

מחלקת השגיאה עדיין נקבעת לפי הסטטוס: שגיאת 404 היא NotFoundError, לא משנה מה כתוב בגוף. כשאין בגוף טקסט קריא, נשארת ההודעה שהמחלקה מגדירה כברירת מחדל, כגון "Not found" (לא נמצא). המחלקה InsufficientCreditsError קוראת את required ואת available מהמעטפת, או את השדות required ו-balance שהשרת שולח לצידה. במכסה לכל משתמש, הערך של available נלקח מ-remaining.

שאלות נפוצות

איך תופסים שגיאות של ה-API של Nodaro ב-TypeScript?

עטפו את הקריאה ב-try/catch ובדקו את השגיאה עם instanceof, מהמחלקה הספציפית ביותר ועד NodaroError בסוף. כל המחלקות מיוצאות מ-‎@nodaro/sdk.

מה קורה כשאין בחשבון מספיק קרדיטים?

הקריאה זורקת InsufficientCreditsError עם סטטוס HTTP 402, לפני שעבודה כלשהי מתחילה. השדות required ו-available של השגיאה מראים כמה קרדיטים ההרצה צריכה וכמה קרדיטים יש בחשבון.

האם שגיאת JobTimeoutError מבטלת את המשימה?

לא. המשימה ממשיכה לרוץ, ובדרך כלל גם מסתיימת. בדקו אותה מאוחר יותר עם client.jobs.get(jobId)‎, או הגדילו את maxMs למודלים איטיים.

האם כדאי לנסות שוב אחרי שגיאת RateLimitedError?

כן, אחרי הפסקה. המתינו כמה שניות, הכפילו את זמן ההמתנה אחרי כל תשובת 429 חדשה, והפסיקו אחרי כמה ניסיונות.

למה שגיאת 403 לא מציינת את קוד הסיבה המדויק?

רוב תשובות ה-403 מגיעות כ-ForbiddenError עם הקוד forbidden. את הסיבה קוראים ב-message, ואת ההרשאה החסרה ב-missingScope, כשחסרה הרשאת OAuth. מודל שנדחה הוא היוצא מן הכלל: השגיאה עליו מגיעה כ-ModelUnavailableError, עם קוד משלה.

עודכן לאחרונה

בדף הזה