From 8aa0ccd8dce81bc5962933470285ffe6a73eabbf Mon Sep 17 00:00:00 2001 From: Claudio Poli Date: Mon, 22 May 2023 19:26:32 +0200 Subject: [PATCH] feat(README.md): add OpenNext section to explain how to deploy on AWS using Serverless Framework plugin fix(app/_actions.ts): import Notifier from @airbrake/node to use it in sendAirbrakeNodeException function feat(app/_actions.ts): add sendAirbrakeNodeException function to send test exception to Airbrake using Node.js feat(components/NoData.tsx): add button to send test exception to Airbrake using Node.js feat(next.config.js): add @airbrake/node to serverComponentsExternalPackages in experimental configuration feat(package.json): add @airbrake/node dependency to the project --- README.md | 4 ++++ app/_actions.ts | 27 +++++++++++++++++++++++++ components/NoData.tsx | 47 ++++++++++++++++++++++++++++--------------- next.config.js | 2 +- package.json | 1 + yarn.lock | 13 ++++++++++++ 6 files changed, 77 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index fd8e8670..398027c7 100644 --- a/README.md +++ b/README.md @@ -120,6 +120,10 @@ make run You can override the default values in the `docker-compose.yml` file by creating a `docker-compose.override.yml` file in the same directory. This file is ignored by Git and will not be committed to the repository. +### OpenNext + +For deploying on AWS beside Amplify you might want to use [OpenNext](https://github.com/serverless-stack/open-next) which is a Serverless Framework plugin for deploying Next.js applications on AWS. + ## Setup Please view all the available configuration variables in the [`.env.dist`](https://github.com/icoretech/airbroke/blob/main/.env.dist) file. diff --git a/app/_actions.ts b/app/_actions.ts index fc5e6ed0..e2deca6c 100644 --- a/app/_actions.ts +++ b/app/_actions.ts @@ -3,6 +3,7 @@ import { prisma } from '@/lib/db'; import generateUniqueProjectKey from '@/lib/keygen'; import { parseGitURL } from '@/lib/parseGitUrl'; +import { Notifier as AirbrakeNodeNotifier } from '@airbrake/node'; import { revalidatePath } from 'next/cache'; import { redirect } from 'next/navigation'; @@ -79,3 +80,29 @@ export async function deleteProject(projectId: bigint): Promise { revalidatePath('/projects'); redirect('/projects'); } + +export async function sendAirbrakeNodeException(projectId: bigint, host: string) { + const project = await prisma.project.findUnique({ where: { id: projectId } }); + if (!project) { + throw new Error('Project not found'); + } + + const airbrake = new AirbrakeNodeNotifier({ + projectId: 1, + projectKey: project.api_key, + environment: 'test', + host: host, + remoteConfig: false, + performanceStats: false, + queryStats: false, + }); + + try { + throw new Error('This is a test exception from Airbroke'); + } catch (err) { + await airbrake.notify(err); + } + + revalidatePath(`/projects/${project.id}/notices`) // mm, this sometimes fails, https://www.reddit.com/r/nextjs/comments/13ilupe/nextjs_134_error_invariant_static_generation/ + redirect(`/projects/${project.id}/notices`); +} diff --git a/components/NoData.tsx b/components/NoData.tsx index 5f211c20..3e37147e 100644 --- a/components/NoData.tsx +++ b/components/NoData.tsx @@ -1,5 +1,6 @@ 'use client'; +import { sendAirbrakeNodeException } from '@/app/_actions'; import { Notifier } from '@airbrake/browser'; import { project } from '@prisma/client'; import { useRouter } from 'next/navigation'; @@ -10,7 +11,7 @@ export default function NoData({ project }: { project: project }) { const [isPending, startTransition] = useTransition(); const { refresh } = useRouter(); - const sendTestException = async () => { + const sendAirbrakeJsException = async () => { const airbrake = new Notifier({ projectId: 1, projectKey: project.api_key, @@ -19,11 +20,10 @@ export default function NoData({ project }: { project: project }) { remoteConfig: false, performanceStats: false, queryStats: false, - queueStats: false, }); await airbrake.notify(new Error('This is a test exception from Airbroke')); - startTransition(() => refresh()); + refresh(); }; return ( @@ -32,19 +32,34 @@ export default function NoData({ project }: { project: project }) {

{'No exceptions recorded'}

- +
+ + +
); } diff --git a/next.config.js b/next.config.js index e6a2de3d..5d78f6dc 100644 --- a/next.config.js +++ b/next.config.js @@ -12,7 +12,7 @@ const nextConfig = { }, experimental: { serverActions: true, - serverComponentsExternalPackages: ['@prisma/client', 'chatgpt', '@octokit'], + serverComponentsExternalPackages: ['@prisma/client', 'chatgpt', '@octokit', '@airbrake/node'], }, async rewrites() { return [ diff --git a/package.json b/package.json index b576fd6b..1c6099a8 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ }, "dependencies": { "@airbrake/browser": "^2.1.8", + "@airbrake/node": "^2.1.8", "@headlessui/react": "^1.7.14", "@prisma/client": "4.14.1", "@tailwindcss/forms": "^0.5.3", diff --git a/yarn.lock b/yarn.lock index 875d6afe..208462c0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -26,6 +26,18 @@ __metadata: languageName: node linkType: hard +"@airbrake/node@npm:^2.1.8": + version: 2.1.8 + resolution: "@airbrake/node@npm:2.1.8" + dependencies: + "@airbrake/browser": ^2.1.8 + cross-fetch: ^3.1.5 + error-stack-parser: ^2.0.4 + tdigest: ^0.1.1 + checksum: 59dca142aee8b0efc0ff90438df27c6cd641307463e364f7b56e2bc48a9c19dc5c599fc1417443e00319bb5040d41456b34a4e139a6f47dcbacc14b5788fbf03 + languageName: node + linkType: hard + "@alloc/quick-lru@npm:^5.2.0": version: 5.2.0 resolution: "@alloc/quick-lru@npm:5.2.0" @@ -1907,6 +1919,7 @@ __metadata: resolution: "airbroke@workspace:." dependencies: "@airbrake/browser": ^2.1.8 + "@airbrake/node": ^2.1.8 "@headlessui/react": ^1.7.14 "@jest/globals": ^29.5.0 "@prisma/client": 4.14.1