# IFERROR & IFNA Functions

Canonical page: https://www.adaptabletools.com/docs/adaptable-ql-expression-advanced-iferror

- AdapTableQL can catch evaluation errors in Expressions, Excel-style:
  - `IFERROR` — return a fallback when evaluation throws any error
  - `IFNA` — return a fallback only when the value is N/A
  - `NA` — produce an N/A error for `IFNA` / `IFERROR` to catch

Most Expressions return a value or a boolean. Sometimes evaluation **fails** — for example dividing by zero, or a lookup that has no result.

AdapTableQL provides 3 Functions for that case, matching Excel:

| Function | What it does |
| -------- | ------------ |
| `IFERROR(value, fallback)` | Evaluates `value`; if that throws an error, returns `fallback` |
| `IFNA(value, fallback)` | Evaluates `value`; if that is N/A, returns `fallback`. Other errors are **not** caught |
| `NA()` | Throws an N/A error (Excel `#N/A`) |

```ts [[1, 1, "IFERROR"], [1, 2, "IFNA"], [1, 3, "NA"]]
 IFERROR([github_stars] / [open_pr_count], 0)
 IFNA(QUERY("Lookup"), "missing")
 NA()
```

- `IFERROR` and `IFNA` only evaluate the fallback when it is needed
- An uncaught error in a [Calculated Column](https://www.adaptabletools.com/docs/handbook-calculated-column/index.md) cell is shown as `#INVALID`

## `IFERROR`

Use `IFERROR` when any evaluation error should become a safe value — typically in a Calculated Column.

A common case is division by zero (`DIV` throws):

```ts [[1, 1, "IFERROR"], [2, 1, "/"], [4, 1, "0"]]
 IFERROR([github_stars] / [open_pr_count], 0)
```

`IFERROR` also catches N/A, so it is the wider of the two wrappers.

## `IFNA` and `NA`

Use `NA()` when a result is **not available** (a failed lookup, or a `CASE` branch with no mapping). Use `IFNA` when only that sentinel should be replaced:

```ts [[1, 1, "IFNA"], [1, 1, "NA", 55], [4, 1, "other"]]
 IFNA(CASE [language] WHEN 'JavaScript' THEN '.js' WHEN 'TypeScript' THEN '.ts' ELSE NA() END, 'other')
```

Other evaluation errors (division by zero, a bad `DATE`, a missing Column) still throw — wrap those with `IFERROR` instead.

`NULL` is a blank value, not an error. `IFNA` and `IFERROR` do not treat blank cells as N/A. Use `COALESCE` or `IS_BLANK` for empty values.

**Example: AdapTableQL: IFERROR and IFNA**

Catching evaluation errors with IFERROR, IFNA and NA

- This demo contains 2 Calculated Columns that wrap Expressions which can fail:
  - `Stars per Open PR` uses `IFERROR` so a row with 0 open PRs returns `0` instead of `#INVALID`
  - `File Type` uses `IFNA` and `NA()` so an unmapped `Language` returns `"other"`

- Find **riot** — it has 0 open PRs; `Stars per Open PR` is `0` (without `IFERROR` that cell would be `#INVALID`)
- Find **alpine** or **polymer** — `Language` is HTML, so `File Type` is `other`

Demo project (Vanilla); the files without a marker are shown below:

```text
src/
  adaptableOptions.ts
  agGridModules.ts     [template]
  columnDefs.ts        [template]
  gridOptions.ts       [template]
  index.ts             [template]
  onAdaptableReady.ts  [template]
  rowData.ts           [template]
  styles.css           [template]
index.html             [template]
package.json           [template]
tsconfig.json          [template]
```

Files marked `[template]` are the same in every demo; see the [demo template](https://www.adaptabletools.com/llms/demo-template.md#vanilla).

**`src/adaptableOptions.ts`**

```ts
import {AdaptableOptions} from '@adaptabletools/adaptable';
import {WebFramework} from './rowData';

export const adaptableOptions: AdaptableOptions<WebFramework> = {
  primaryKey: 'id',
  adaptableId: 'IFERROR and IFNA',
  initialState: {
    Dashboard: {
      ModuleButtons: ['CalculatedColumn'],
    },
    StatusBar: {
      StatusBars: [
        {
          Key: 'Center Panel',
          StatusBarPanels: ['Layout', 'CalculatedColumn'],
        },
      ],
    },
    Theme: {CurrentTheme: 'dark'},
    Layout: {
      CurrentLayout: 'Standard Layout',
      Layouts: [
        {
          TableColumns: [
            'name',
            'language',
            'github_stars',
            'open_pr_count',
            'stars_per_open_pr',
            'file_type',
            'license',
            'github_watchers',
          ],
          Name: 'Standard Layout',
          AutoSizeColumns: true,
        },
      ],
    },
    CalculatedColumn: {
      CalculatedColumns: [
        {
          FriendlyName: 'Stars per Open PR',
          ColumnId: 'stars_per_open_pr',
          Expression: 'IFERROR([github_stars] / [open_pr_count], 0)',
          CalculatedColumnSettings: {
            DataType: 'number',
          },
        },
        {
          FriendlyName: 'File Type',
          ColumnId: 'file_type',
          Expression:
            "IFNA(CASE [language] WHEN 'JavaScript' THEN '.js' WHEN 'TypeScript' THEN '.ts' ELSE NA() END, 'other')",
          CalculatedColumnSettings: {
            DataType: 'text',
          },
        },
      ],
    },
  },
};
```

- See [Logic in Expressions](https://www.adaptabletools.com/docs/adaptable-ql-expression-advanced-logic/index.md) for `IF` and `CASE`
- See the [Functions Library](https://www.adaptabletools.com/docs/adaptable-ql-expression-functions/index.md) for signatures and examples
