Lingara Lingara Τεκμηρίωση Οδηγοί API Βιβλιοθήκες Εφαρμογές Δημιουργία Διαδικτυακή εφαρμογή
Γλώσσα: Ελληνικά

Σφάλματα και επαναλήψεις

Αυτή η σελίδα έχει μεταφραστεί από τα αγγλικά. Αν οι δύο διαφέρουν, η αγγλική σελίδα είναι η σωστή. Διαβάστε την αγγλική σελίδα

Κάθε αποτυχία που εγείρει μια βιβλιοθήκη είναι ένα από τέσσερα σφάλματα, και και τα τέσσερα μοιράζονται έναν βασικό τύπο, ώστε ένας μόνο handler να τα πιάνει όλα.

  • Σφάλμα API. Το API αρνήθηκε το αίτημα. Περιέχει την κατάσταση HTTP, ένα σταθερό code για διακλάδωση και ένα μήνυμα στη γλώσσα που ζητήσατε.
  • Σφάλμα OAuth. Το endpoint token απέρριψε τα διαπιστευτήριά σας ή τα scopes που ζητήσατε.
  • Σφάλμα συντήρησης. Το API δεν είναι διαθέσιμο για λίγο λόγω συντήρησης.
  • Σφάλμα μεταφοράς. Δεν έφτασε αξιοποιήσιμη απάντηση: η σύνδεση απέτυχε ή έληξε ο χρόνος της, ή η απάντηση δεν μπόρεσε να διαβαστεί.

Η ακύρωση μιας κλήσης δεν είναι σφάλμα. Εμφανίζεται ως ο μηχανισμός ακύρωσης της δικής σας γλώσσας.

Τι επαναλαμβάνεται

Ένα 429 ή 503 που δηλώνει πόση αναμονή χρειάζεται, σε κεφαλίδα Retry-After 60 δευτερολέπτων ή λιγότερο, επαναλαμβάνεται μετά από ακριβώς αυτή την αναμονή. Μια κλήση κάνει το πολύ 3 προσπάθειες. Μπορείτε να απενεργοποιήσετε τις επαναλήψεις ορίζοντας το μέγιστο σε 1.

Οτιδήποτε άλλο εγείρεται αμέσως:

  • ένα 429 ή 503 χωρίς Retry-After·
  • μια αναμονή μεγαλύτερη από 60 δευτερόλεπτα, την οποία η βιβλιοθήκη δεν θα περάσει μέσα στην κλήση σας. Το σφάλμα περιέχει retry_after, ώστε να προγραμματίσετε μόνοι σας την επανάληψη·
  • ένα σφάλμα μεταφοράς, επειδή το αίτημα μπορεί να έχει ήδη φτάσει στο API·
  • οποιαδήποτε ροή έχει ήδη παραδώσει ένα συμβάν.
Γλώσσα παραδείγματος κώδικα

TypeScript

import { ApiError, MaintenanceError, OAuthError, TransportError } from "@lingara/api";

try {
  await client.getUsage();
} catch (e) {
  if (e instanceof ApiError) {
    // A refusal from the API: e.status, e.code (stable) and e.message (localised).
    console.error(e.status, e.code, e.message, e.retryAfter ?? "");
  } else if (e instanceof OAuthError) {
    // The token endpoint refused the credentials or the scopes.
    console.error(e.status, e.error, e.description ?? "");
  } else if (e instanceof MaintenanceError) {
    console.error("under maintenance; retry after", e.retryAfter ?? "a while");
  } else if (e instanceof TransportError) {
    // No usable answer: connect, tls, reset, timeout, and so on.
    console.error("transport:", e.kind);
  } else {
    throw e;
  }
}

Rust

use lingara::Error;

let result = client.get_usage().await;
if let Some(wait) = result.as_ref().err().and_then(Error::retry_after) {
    eprintln!("the API asks you to retry after {wait:?}");
}
match result {
    Ok(usage) => println!("{} allowance rows", usage.allowance.len()),
    // A refusal from the API: status, code (stable) and message (localised).
    Err(Error::Api(e)) => eprintln!("{} {} {}", e.status, e.code, e.message),
    // The token endpoint refused the credentials or the scopes.
    Err(Error::OAuth(e)) => eprintln!("{} {} {}", e.status, e.error, e.description.unwrap_or_default()),
    Err(Error::Maintenance(_)) => eprintln!("the API is under maintenance"),
    // No usable answer: connect, tls, reset, timeout, and so on.
    Err(Error::Transport(e)) => eprintln!("transport: {}", e.kind),
    Err(other) => return Err(other.into()),
}

Go

_, err := client.GetUsage(ctx)
var apiErr *lingara.APIError
var oauthErr *lingara.OAuthError
var maintenance *lingara.MaintenanceError
var transport *lingara.TransportError
switch {
case err == nil:
case errors.As(err, &apiErr):
	// A refusal from the API: Status, Code (stable) and Message (localised).
	fmt.Println(apiErr.Status, apiErr.Code, apiErr.Message)
	if apiErr.RetryAfter != nil {
		fmt.Println("retry after", *apiErr.RetryAfter)
	}
case errors.As(err, &oauthErr):
	// The token endpoint refused the credentials or the scopes.
	fmt.Println(oauthErr.Status, oauthErr.ErrorCode, oauthErr.Description)
case errors.As(err, &maintenance):
	fmt.Println("under maintenance")
	if maintenance.RetryAfter != nil {
		fmt.Println("retry after", *maintenance.RetryAfter)
	}
case errors.As(err, &transport):
	// No usable answer: connect, tls, reset, timeout, and so on.
	fmt.Println("transport:", transport.Kind)
default:
	// ctx was cancelled or timed out: errors.Is(err, context.Canceled).
	fmt.Println(err)
}

Java

try {
  client.getUsage();
} catch (LingaraException e) {
  if (e instanceof ApiException api) {
    // A refusal from the API: status(), code() (stable) and getMessage() (localised).
    System.out.println(api.status() + " " + api.code() + " " + api.getMessage());
    api.retryAfter().ifPresent(wait -> System.out.println("retry after " + wait));
  } else if (e instanceof OAuthException oauth) {
    // The token endpoint refused the credentials or the scopes.
    System.out.println(oauth.status() + " " + oauth.error() + " " + oauth.description());
  } else if (e instanceof MaintenanceException maintenance) {
    System.out.println("under maintenance");
    maintenance.retryAfter().ifPresent(wait -> System.out.println("retry after " + wait));
  } else if (e instanceof TransportException transport) {
    // No usable answer: CONNECT, TLS, RESET, TIMEOUT, and so on.
    System.out.println("transport: " + transport.kind());
  }
}
// An interrupted call throws java.util.concurrent.CancellationException instead.

Kotlin

try {
    client.getUsage()
} catch (e: LingaraException) {
    when (e) {
        // A refusal from the API: status, code (stable) and message (localised).
        is ApiException -> println("${e.status} ${e.code} ${e.message}; retry after ${e.retryAfter}")
        // The token endpoint refused the credentials or the scopes.
        is OAuthException -> println("${e.status} ${e.error} ${e.description}")
        is MaintenanceException -> println("under maintenance; retry after ${e.retryAfter}")
        // No usable answer: CONNECT, TLS, RESET, TIMEOUT, and so on.
        is TransportException -> println("transport: ${e.kind}")
    }
}
// A cancelled call throws the caller's own CancellationException instead.

Ruby

begin
  client.get_usage
rescue Lingara::ApiError => e
  # A refusal from the API: status, code (stable) and message (localised).
  puts "#{e.status} #{e.code}: #{e.message}"
  puts "retry after #{e.retry_after}s" if e.retry_after
rescue Lingara::OAuthError => e
  # The token endpoint refused the credentials or the scopes.
  puts "#{e.status} #{e.error}: #{e.description}"
rescue Lingara::MaintenanceError => e
  puts "under maintenance"
  puts "retry after #{e.retry_after}s" if e.retry_after
rescue Lingara::TransportError => e
  # No usable answer: :connect, :tls, :reset, :timeout, and so on.
  puts "transport: #{e.kind}"
end

PHP

use Lingara\Exception\ApiException;
use Lingara\Exception\LingaraException;
use Lingara\Exception\MaintenanceException;
use Lingara\Exception\OAuthException;
use Lingara\Exception\TransportException;

try {
    $client->getUsage();
} catch (LingaraException $e) {
    if ($e instanceof ApiException) {
        // A refusal from the API: status, errorCode (stable) and message (localised).
        echo $e->status(), ' ', $e->errorCode(), ': ', $e->getMessage(), "\n";
        echo 'retry after: ', $e->retryAfter() ?? 'not given', "\n";
    } elseif ($e instanceof OAuthException) {
        // The token endpoint refused the credentials or the scopes.
        echo $e->status(), ' ', $e->error(), ': ', $e->description(), "\n";
    } elseif ($e instanceof MaintenanceException) {
        echo 'under maintenance; retry after: ', $e->retryAfter() ?? 'not given', "\n";
    } elseif ($e instanceof TransportException) {
        // No usable answer: connect, tls, reset, timeout, and so on.
        echo 'transport: ', $e->kind()->value, "\n";
    }
}