The Fauna service will be ending on May 30, 2025.

For more information on the service wind down, see our announcement and the Fauna Service End-of-Life FAQ.

abort()

End the current query and return an abort error with a user-defined abort value.

Signature

abort(return: Any) => Never

Description

abort() lets you intentionally return an abort error in an FQL query or user-defined function (UDF). You can pass a user-defined return value to abort(). For example, in a UDF:

function checkout(orderId, status, payment) {
  ...
  // Abort the query if it calls `checkout()` with a
  // `status` other than `processing`.
  if (status != "processing") {
    // `Abort()` accepts a user-defined return value.
    // The value can be of any FQL type.
    abort("Cannot call checkout with status other than processing.")
  }
}

Calling abort() ends the current query, including all expressions in query, and returns an abort error. No operations in the query are committed. Changes made before the abort() call are discarded.

Abort errors

Abort errors have the abort error code, a Query aborted. error message, and include the user-defined return value in the Query HTTP API endpoint response’s error.abort response body property:

{
  "error": {
      "code": "abort",
      "message": "Query aborted.",
      "abort": "Cannot call checkout with status other than processing."
  },
  ...
}

The return value is encoded from FQL to JSON using the data format specified in the X-Format header.

Query stack traces

Abort errors include a query stack trace in the response’s summary field. The stack trace includes the lines that triggered the error.

For example, the following FQL query includes an abort() call:

Customer.all()
abort("Discard")

The query as a Query endpoint request:

curl -X POST \
'https://db.fauna.com/query/1' \
-H "Authorization: Bearer $FAUNA_SECRET" \
-H 'Content-Type: application/json' \
-H 'X-Format: tagged' \
-d '{
  "query": "Customer.all()\nabort(\"Discard\")"
}'

Response:

{
    "error": {
        "code": "abort",
        "message": "Query aborted.",
        "abort": "Discard"
    },
    "summary": "error: Query aborted.\nat *query*:2:6\n  |\n2 | abort(\"Discard\")\n  |      ^^^^^^^^^^^\n  |",
    ...
}

When unescaped, the response’s summary renders as:

error: Query aborted.
at *query*:2:6
  |
2 | abort("Discard")
  |      ^^^^^^^^^^^
  |

Query stack traces for UDF calls

When calling a user-defined function (UDF) that uses abort(), the summary’s query stack trace includes both query and UDF lines if the authentication secret has the built-in admin or server role.

For example, the following response’s summary field contains a query stack trace with both query and UDF lines:

{
  "error": {
      "code": "abort",
      "message": "Query aborted.",
      "abort": "Can not call checkout with status other than processing."
  },
  "summary": "error: Query aborted.\nat *udf:checkout*:6:10\n  |\n6 | abort(\"Can not call checkout with status other than processing.\")\n  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n  |\nat *query*:1:9\n  |\n1 | checkout(420701723228635213, \"cart\", {})\n  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n  |\n\ninfo at *udf:checkout*:3: log - test123\n\ninfo: \"debug - test123\"\nat *udf:checkout*:4:6\n  |\n4 | dbg(\"debug - test123\")\n  |      ^^^^^^^^^^^^^^^^^^^\n  |",
  ...
}

When unescaped, the response’s summary renders as:

error: Query aborted.
at *udf:checkout*:6:10
  |
6 | abort("Can not call checkout with status other than processing.")
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
at *query*:1:9
  |
1 | checkout(420701723228635213, "cart", {})
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |

info at *udf:checkout*:3: log - test123

info: "debug - test123"
at *udf:checkout*:4:6
  |
4 | dbg("debug - test123")
  |      ^^^^^^^^^^^^^^^^^^^
  |

For secrets with the built-in server-readonly role or a user-defined role, the summary’s stack trace only includes query lines, not UDF lines. This applies even if the UDF is annotated with @role(admin) or @role(server). This prevents unprivileged users from inferring sensitive UDF logic or data.

For example, the previous response’s summary field contains a query stack trace with only query lines:

{
  "error": {
      "code": "abort",
      "message": "Query aborted.",
      "abort": "Can not call checkout with status other than processing."
  },
  "summary": "error: Query aborted.\nat *query*:1:9\n  |\n1 | checkout(420701723228635213, \"cart\", {})\n  |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n  |",
  ...
}

When unescaped, the response’s summary renders as:

error: Query aborted.
at *query*:1:9
  |
1 | checkout(420701723228635213, "cart", {})
  |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |

Abort errors in client drivers

Fauna’s client drivers include classes for abort errors:

Parameters

Parameter Type Required Description

return

Any

true

User-defined value returned in the error.abort property of abort error responses.

The return value is encoded from FQL to JSON using the data format specified in the Query HTTP API request's X-Format header.

Return value

Type Description

Never

abort() never returns a value. Queries that call abort() always return an abort error, not query results.

Examples

Basic example

The following query contains two expressions:

  • A collection.create() call to create a Customer collection document.

  • An abort() call that aborts the query.

Customer.create({
  name: "John Doe",
  email: "jdoe@example.com",
  address: {
    street: "87856 Mendota Court",
    city: "Washington",
    state: "DC",
    postalCode: "20220",
    country: "US"
  }
})
abort("Something went wrong") // Stops the query and returns an error

The query returns an abort error:

abort: Query aborted.

error: Query aborted.
at *query*:12:6
   |
12 | abort("Something went wrong")
   |      ^^^^^^^^^^^^^^^^^^^^^^^^
   |

As a Query HTTP API endpoint response using the simple data format:

{
  "error": {
    "code": "abort",
    "message": "Query aborted.",
    "abort": "Something went wrong"
  },
  ...
}

Because the query included an abort() call, the collection.create() operation is not committed. The related document isn’t created.

To verify the document wasn’t created, you can run use an index to run an exact match search for the document:

Customer.byEmail("jdoe@example.com")

The query returns an empty Set, indicating the document wasn’t created:

{
  data: []
}

Using abort() in UDFs

abort() is commonly used in user-defined function (UDF) to raise errors. You can use abort() to intentionally raise an error if the UDF is passed an invalid argument.

For example, the following FSL function schema defines a UDF that includes several abort() calls nested within conditional logic:

function validateOrderStatusTransition(oldStatus, newStatus) {
  if (oldStatus == "cart" && newStatus != "processing") {
    // The order can only transition from cart to processing.
    abort("Invalid status transition.")
  } else if (oldStatus == "processing" && newStatus != "shipped") {
    // The order can only transition from processing to shipped.
    abort("Invalid status transition.")
  } else if (oldStatus == "shipped" && newStatus != "delivered") {
    // The order can only transition from shipped to delivered.
    abort("Invalid status transition.")
  }
}

Pass non-string values to abort()

abort() accepts a single return parameter of Any type. This value is returned in the Query HTTP API endpoint response’s error.abort response body property.

The return value is encoded from FQL to JSON using the data format specified in the Query HTTP API request's X-Format header.

Pass an Array value

The following abort() call contains an Array as a return value:

abort([1, 2, 3])

The query as a Query endpoint request using the simple data format:

curl -X POST \
'https://db.fauna.com/query/1' \
-H "Authorization: Bearer $FAUNA_SECRET" \
-H 'Content-Type: application/json' \
-H 'X-Format: simple' \
-d '{
  "query": "abort([1, 2, 3])"
}'

The API response:

{
  "error": {
    "code": "abort",
    "message": "Query aborted.",
    "abort": [ 1, 2, 3 ]
  },
  ...
}

The query as a Query endpoint request using the tagged data format:

curl -X POST \
'https://db.fauna.com/query/1' \
-H "Authorization: Bearer $FAUNA_SECRET" \
-H 'Content-Type: application/json' \
-H 'X-Format: tagged' \
-d '{
  "query": "abort([1, 2, 3])"
}'

The API response:

{
  "error": {
    "code": "abort",
    "message": "Query aborted.",
    "abort": [
      {
        "@int": "1"
      },
      {
        "@int": "2"
      },
      {
        "@int": "3"
      }
    ]
  },
  ...
}

Pass a Time value

The following abort() call contains an Time as a return value:

abort(Time.now())

The query as a Query endpoint request using the simple data format:

curl -X POST \
'https://db.fauna.com/query/1' \
-H "Authorization: Bearer $FAUNA_SECRET" \
-H 'Content-Type: application/json' \
-H 'X-Format: simple' \
-d '{
  "query": "abort(Time.now())"
}'

The API response:

{
  "error": {
    "code": "abort",
    "message": "Query aborted.",
    "abort": "2025-02-21T16:00:00.253411Z"
  },
  ...
}

The query as a Query endpoint request using the tagged data format:

curl -X POST \
'https://db.fauna.com/query/1' \
-H "Authorization: Bearer $FAUNA_SECRET" \
-H 'Content-Type: application/json' \
-H 'X-Format: tagged' \
-d '{
  "query": "abort(Time.now())"
}'

The API response:

{
  "error": {
    "code": "abort",
    "message": "Query aborted.",
    "abort": {
      "@time": "2025-02-21T16:00:33.691141Z"
    }
  },
  ...
}
\