Appearance
Error Handling
The primaTime API uses a structured approach to error handling that follows GraphQL best practices. Understanding error types and how to handle them is essential for building robust integrations.
Error Response Structure
GraphQL-Level Errors
When a request fails at the GraphQL layer (authentication, parsing, etc.), errors appear in the top-level errors array:
json
{
"errors": [
{
"message": "Invalid access token",
"locations": [{ "line": 2, "column": 3 }],
"path": ["projects"],
"extensions": {
"classification": "UNAUTHORIZED"
}
}
],
"data": null
}Business-Level Errors
For mutations, business logic errors are returned in the errors field of the payload:
json
{
"data": {
"createProject": {
"project": null,
"errors": [
{
"__typename": "FieldError",
"value": "Code already exists",
"field": "code"
}
]
}
}
}Error Types
The API defines several error types implementing the UserError interface:
MessageError
A general error message not tied to a specific field:
graphql
type MessageError implements UserError {
value: String!
}Example:
json
{
"__typename": "MessageError",
"value": "Operation not permitted"
}FieldError
An error associated with a specific input field:
graphql
type FieldError implements UserError {
value: String!
field: String!
}Example:
json
{
"__typename": "FieldError",
"value": "Must be at least 3 characters",
"field": "title"
}AccountNotVerifiedError
Returned when attempting to access features with an unverified email:
graphql
type AccountNotVerifiedError implements UserError {
value: String!
email: String!
}Example:
json
{
"__typename": "AccountNotVerifiedError",
"value": "Please verify your email address",
"email": "user@example.com"
}InvalidVerificationTokenError
Returned when email verification token is invalid or expired:
graphql
type InvalidVerificationTokenError implements UserError {
value: String!
}InvalidSessionError
Returned when the session is invalid or expired:
graphql
type InvalidSessionError implements UserError {
value: String!
}ExpiredInviteError
Returned when attempting to use an expired invitation:
graphql
type ExpiredInviteError implements UserError {
value: String!
}InviteNotFoundError
Returned when an invitation code is invalid:
graphql
type InviteNotFoundError implements UserError {
value: String!
}CooldownPeriodError
Returned when an action is rate-limited:
graphql
type CooldownPeriodError implements UserError {
value: String!
expiresAt: DateTime!
}Example:
json
{
"__typename": "CooldownPeriodError",
"value": "Please wait before trying again",
"expiresAt": "2024-01-15T10:30:00.000Z"
}Querying for Errors
Always include the errors field with type discrimination in mutations:
graphql
mutation CreateProject($data: ProjectInput!) {
createProject(data: $data) {
project {
id
title
}
errors {
__typename
value
... on FieldError {
field
}
... on CooldownPeriodError {
expiresAt
}
}
}
}Payload Interface
All mutation payloads implement the Payload interface:
graphql
interface Payload {
errors: [UserError!]!
}Some payloads also implement ResultPayload for simple success/failure results:
graphql
interface ResultPayload implements Payload {
success: Boolean!
errors: [UserError!]!
}Check success before processing results:
graphql
mutation Login($data: PasswordLoginInput!) {
loginWithPassword(data: $data) {
success
errors {
__typename
value
... on FieldError { field }
}
}
}Debugging Errors
When encountering unexpected errors:
- Check the
__typename— Understand what type of error occurred - Check
extensions— May contain additional context - Check
path— Shows which field or resolver failed - Check
locations— Points to the query location - Use GraphiQL — Test queries interactively with full error details