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 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. Changes made before the abort() call are discarded.

Abort errors

Abort errors use the abort error code and include the user-defined return value in the Query HTTP API endpoint'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 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 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

This simple example shows how to abort a query.

Create a document in the collection and abort 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("Discard")
abort: Query aborted.

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

 

Run Customer.all() to verify that a customer with the last name of Jones wasn’t added.

The following example creates an anonymous function, which aborts when called without a valid email argument:

let createCustomer = (email) => {
  if (email.length <= 0) {
    abort({
      code: "invalid_email",
      message: "user email must be non-empty"
    })
  }
  Customer.create({
    name: "Jane Doe",
    email: email,
    address: {
      street: "87856 Mendota Court",
      city: "Washington",
      state: "DC",
      postalCode: "20220",
      country: "US"
    }
  })
}

createCustomer("fake@example.com")
createCustomer("")
abort: Query aborted.

error: Query aborted.
at *query*:3:10
  |
3 |       abort({
  |  __________^
4 | |       code: "invalid_email",
5 | |       message: "user email must be non-empty"
6 | |     })
  | |______^
  |
at *query*:22:15
   |
22 | createCustomer("")
   |               ^^^^
   |

The first call to createCustomer() succeeds. The second call fails because a valid email argument isn’t included, which triggers the abort() action.

The response message is the notification response.

Notice that the query runs all the statements included in the query.

\