Skip to content

Commit

Permalink
Add info on searching errors (#1068)
Browse files Browse the repository at this point in the history
* Add info on searching errors

* Fix docs search auto-focus
  • Loading branch information
djfarrelly authored Feb 14, 2025
1 parent 05281c0 commit a9e3ccd
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 17 deletions.
4 changes: 2 additions & 2 deletions components/AnnouncementBanner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ export default function AnnouncementBanner() {

return (
<Banner href="https://innge.st/devweek-25">
Catch our talk on Orchestrating Agentic AI Workflows- claim a free pass to
DevWeek's live replay
Sign-up to catch a live replay of “Orchestrating Agentic AI Workflows
from DevWeek
</Banner>
);
}
6 changes: 6 additions & 0 deletions pages/docs/guides/writing-expressions.mdx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { Info } from "src/shared/Docs/mdx";

# Writing expressions

Expressions are used in a number of ways for configuring your functions. They are used for:
Expand Down Expand Up @@ -103,6 +105,10 @@ Most expressions are given the `event` payload object as the input. Expressions
* Use ternary operators to return default values
* When using the or operator (`||`), CEL will always return a boolean. This is different from JavaScript, where the or operator returns the value of the statement left of the operator if truthy. Use the ternary operator (`?`) instead of `||` for conditional returns.

<Info>
Please note that while CEL supports a wide range of helpers and macros, Inngest only supports a subset of these to ensure a high level of performance and reliability.
</Info>

{/* TODO - Omit these advanced macros for now until we review support individually
### CEL Helpers & Macros
Expand Down
71 changes: 67 additions & 4 deletions pages/docs/platform/monitor/inspecting-function-runs.mdx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Callout, Row, Col } from "src/shared/Docs/mdx";
import { Callout, Tip, Row, Col } from "src/shared/Docs/mdx";
import { RiExternalLinkFill } from "@remixicon/react";

# Inspecting a Function run
Expand All @@ -14,12 +14,13 @@ Functions runs across all application of the currently [selected environment](/d

_Runs can be filtered using a Status, Queued or Started at and Application filters._

Accessing the runs of a specific Function is achieved via the "Functions" menu, as described in [the function run details section](http://localhost:3002/docs/platform/monitor/inspecting-function-runs#the-function-run-details).
Accessing the runs of a specific Function is achieved via the "Functions" menu, as described in [the function run details section](/docs/platform/monitor/inspecting-function-runs#the-function-run-details).

## Searching Function runs
Advanced filters are available using a [CEL expression](https://www.inngest.com/docs/guides/writing-expressions). The search feature is available by clicking on the "Show search" button next to the other run filters.
Advanced filters are available using a [CEL expression](/docs/guides/writing-expressions). The search feature is available by clicking on the "Show search" button next to the other run filters.

![The runs list features an advance search feature that filters results using a CEL query.](/assets/docs/platform/monitor/inspecting-function-runs/function-runs-search.png)

### Searchable properties
Only basic search operators and `event` and `output` variables are available for now:

Expand All @@ -32,7 +33,69 @@ event.v| `string`| `==`, `!=`
event.data| `map[string]any`| `==`, `!=`, `>`, `>=`, `<`, `<=`
output| `any`| `==`, `!=`, `>`, `>=`, `<`, `<=`

A few examples of valid search queries are `event.data.hello == "world"` and `output.success != true`. [Learn more about how expressions are used in Inngest.](https://www.inngest.com/docs/guides/writing-expressions)
A few examples of valid search queries are `event.data.hello == "world"` and `output.success != true`. [Learn more about how expressions are used in Inngest.](/docs/guides/writing-expressions)

<Tip>
You can combine multiple search queries using the `&&` operator or `||` operator. Adding a new line is the equivalent of using the `&&` operator.
</Tip>

### Searching for errors

Errors are serialized as JSON on the `output` object. When supported by the language SDK, errors are deserialized into a structured object. Here is an example of a error in TypeScript:

```typescript {{ title: "Example TypeScript code" }}
throw new NonRetriableError("Failed to import data");
```

```json {{ title: "Example TypeScript error" }}
{
"name": "NonRetriableError",
"message": "Failed to import data",
"stack": "NonRetriableError: Failed to import data\n at V1InngestExecution.userFnToRun (/opt/render/project/src/build/inngest/ai.js:143:15) ..."
}
```

This error can be searched using the following CEL expression:

```
output.name == "NonRetriableError" && output.message == "Failed to import data"
```

<Tip>
Using custom error types in TypeScript can make it easier to search by the type of error:

<details>
<summary>Example TypeScript code</summary>

```typescript
import { NonRetriableError } from "inngest";

class UserNotFoundError extends NonRetriableError {
constructor(message: string) {
super(message);
this.name = "UserNotFoundError";
}
}
inngest.createFunction(
{ id: "my-fn" },
{ event: "user" },
async ({ step, event }) => {
await step.run("get-user", async () => {
const user = await getUser(event.data.userId);
if (!user) {
throw new UserNotFoundError(`User not found (${event.data.userId})`);
}
// ...
});
}
);
```

``` {{ title: "Example search query" }}
event.data.userId == "12345" && output.name == "UserNotFoundError"
```
</details>
</Tip>

## The Function run details
A _Handle failed payments_ function failed after retrying 5 times:
Expand Down
4 changes: 3 additions & 1 deletion shared/Docs/Navigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -361,10 +361,11 @@ function NavigationGroup({
nestingLevel > 0,
})}
>
{group.links.map((link) => {
{group.links.map((link, idx) => {
if (isNavGroup(link)) {
return (
<Accordion.Root
key={idx}
type="multiple"
defaultValue={
hasNavGroupPath(link, router.pathname)
Expand Down Expand Up @@ -566,6 +567,7 @@ export function Navigation(props) {
/>
) : (
<NavLink
key={item.title}
isTopLevel={true}
href={item.href}
active={pathname === item.href}
Expand Down
30 changes: 20 additions & 10 deletions shared/Docs/Search.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,12 @@ import {
AutocompleteApi,
} from "@algolia/autocomplete-core";
import { getAlgoliaResults } from "@algolia/autocomplete-preset-algolia";
import { Dialog, Transition } from "@headlessui/react";
import {
Dialog,
DialogPanel,
Transition,
TransitionChild,
} from "@headlessui/react";
import algoliasearch from "algoliasearch/lite";
import clsx from "clsx";

Expand Down Expand Up @@ -346,6 +351,7 @@ const SearchInput = forwardRef<HTMLInputElement, SearchInputProps>(
<SearchIcon className="pointer-events-none absolute left-3 top-0 h-full w-5 stroke-slate-500" />
{/* @ts-ignore */}
<input
data-autofocus
ref={inputRef}
className={clsx(
"flex-auto appearance-none bg-transparent pl-10 text-slate-900 outline-none placeholder:text-carbon-600 focus:w-full focus:flex-none dark:text-white sm:text-sm [&::-webkit-search-cancel-button]:hidden [&::-webkit-search-decoration]:hidden [&::-webkit-search-results-button]:hidden [&::-webkit-search-results-decoration]:hidden",
Expand Down Expand Up @@ -395,6 +401,10 @@ function SearchDialog({
function onRouteChange() {
setOpen(false);
}
// Hack for mobile auto-focus b/c data-autofocus doesn't work there
setTimeout(() => {
inputRef.current?.focus();
}, 100);

router.events.on("routeChangeStart", onRouteChange);
router.events.on("hashChangeStart", onRouteChange);
Expand All @@ -403,7 +413,7 @@ function SearchDialog({
router.events.off("routeChangeStart", onRouteChange);
router.events.off("hashChangeStart", onRouteChange);
};
}, [open, setOpen, router]);
}, [open, setOpen, router, inputRef.current]);

useEffect(() => {
if (open || enableShortcutKey === false) {
Expand Down Expand Up @@ -445,7 +455,7 @@ function SearchDialog({
);

return (
<Transition.Root
<Transition
show={open}
as={Fragment}
afterLeave={() => autocomplete.setQuery("")}
Expand All @@ -454,7 +464,7 @@ function SearchDialog({
onClose={onClose}
className={clsx("fixed inset-0 z-50", className)}
>
<Transition.Child
<TransitionChild
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0"
Expand All @@ -464,10 +474,10 @@ function SearchDialog({
leaveTo="opacity-0"
>
<div className="fixed inset-0 bg-carbon-400/40 backdrop-blur-sm dark:bg-black/40" />
</Transition.Child>
</TransitionChild>

<div className="fixed inset-0 overflow-y-auto px-4 py-4 sm:py-20 sm:px-6 md:py-32 lg:px-8 lg:py-[15vh]">
<Transition.Child
<TransitionChild
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0 scale-95"
Expand All @@ -476,7 +486,7 @@ function SearchDialog({
leaveFrom="opacity-100 scale-100"
leaveTo="opacity-0 scale-95"
>
<Dialog.Panel className="mx-auto overflow-hidden rounded-lg bg-carbon-50 shadow-xl ring-1 ring-carbon-900/7.5 dark:bg-carbon-900 dark:ring-carbon-800 sm:max-w-xl">
<DialogPanel className="mx-auto overflow-hidden rounded-lg bg-carbon-50 shadow-xl ring-1 ring-carbon-900/7.5 dark:bg-carbon-900 dark:ring-carbon-800 sm:max-w-xl">
<div {...autocomplete.getRootProps({})}>
{/* @ts-ignore */}
<form
Expand Down Expand Up @@ -512,11 +522,11 @@ function SearchDialog({
</div>
</form>
</div>
</Dialog.Panel>
</Transition.Child>
</DialogPanel>
</TransitionChild>
</div>
</Dialog>
</Transition.Root>
</Transition>
);
}

Expand Down

0 comments on commit a9e3ccd

Please sign in to comment.