Git Product home page Git Product logo

toucan-js's Introduction

Logo

npm version npm version npm version

toucan-js

Toucan is a Sentry client for Cloudflare Workers written in TypeScript.

  • Reliable: In Cloudflare Workers isolate model, it is inadvisable to set or mutate global state within the event handler. Toucan was created with Workers' concurrent model in mind. No race-conditions, no undelivered logs, no nonsense metadata in Sentry.
  • Flexible: Supports fetch and scheduled Workers, their .mjs equivalents, and Durable Objects.
  • Familiar API: Follows Sentry unified API guidelines.

Documentation

See toucan-js package.

Examples

This repository provides starters written in TypeScript, with source maps support and local live reloading experience using open source Cloudflare Workers runtime.

toucan-js's People

Contributors

andyrichardson avatar called-d avatar dz0ny avatar github-actions[bot] avatar huv1k avatar maciejp-ro avatar nathanclevenger avatar olizilla avatar renovate[bot] avatar robertcepa avatar thibmeu avatar timfish avatar walshydev avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

toucan-js's Issues

WithScope is ignored

Overwriting by using withScope does not work:

toucan.withScope(scope => {
   scope.setTag('ip', 'foo') // this works
   scope.setUser({ ip: 'foo' }) // this does not work
   scope.setTag('environment', 'dev') // this does not work

  // ...
  // captureEvent()
})

It looks like environment and user ip or ip_address cannot be overwritten. Is there a way to do that?

Customizable "logger name"

Great package! ๐Ÿ‘

Unless there's a purpose "EdgeWorker" serves, would be nice if this were a configurable value. Especially since it appears in the Sentry Issues list.

logger: 'EdgeWorker',

Given maintainer approval on an option name, maybe even logger: string;, I'd be happy to contribute this change.

Ability to disable / enable Sentry

Right now, if I have a ToucanJS instance & I want to disable it, I have to add guard checks around it (or make it an | undefined type & invoke it through ? safely). It would be convenient if the ToucanJS instance could be told to disable so that we would still have an instance against which we perform actions but the actual outbound fetches get disabled (& could be reenabled for completeness if needed). This was a confounding factor to some incidents.

Type 'RewriteFrames' is not assignable to type 'Integration'

@sentry/integrations v7.36.0
toucan-js: v3.3.0

This:

import { RewriteFrames } from '@sentry/integrations'
import { Toucan } from 'toucan-js'

interface Env {}

export default {
  async fetch(req: Request, env: Env, ctx: ExecutionContext) {
    new Toucan({
      dsn: '',
      context: ctx,
      request: req,
      release: 'some release',
      integrations: [new RewriteFrames({ root: '/' })],
    })
  }
}

fails with

error TS2322: Type 'RewriteFrames' is not assignable to type 'Integration'.
  Types of property 'setupOnce' are incompatible.
    Type '(addGlobalEventProcessor: (callback: import("node_modules/@sentry/integrations/node_modules/@sentry/types/types/eventprocessor").EventProcessor) => void, getCurrentHub: () => import("node_modules/@sentry/integrations/node_modules/@sentry/typ...' is not assignable to type '(addGlobalEventProcessor: (callback: import("node_modules/@sentry/types/types/eventprocessor").EventProcessor) => void, getCurrentHub: () => import("node_modules/@sentry/types/types/hub").Hub) => void'.
      Types of parameters 'addGlobalEventProcessor' and 'addGlobalEventProcessor' are incompatible.
        Types of parameters 'callback' and 'callback' are incompatible.
          Type 'import("node_modules/@sentry/integrations/node_modules/@sentry/types/types/eventprocessor").EventProcessor' is not assignable to type 'import("node_modules/@sentry/types/types/eventprocessor").EventProcessor'.
            Types of parameters 'hint' and 'hint' are incompatible.
              Type 'import("node_modules/@sentry/types/types/event").EventHint' is not assignable to type 'import("node_modules/@sentry/integrations/node_modules/@sentry/types/types/event").EventHint'.
                Types of property 'captureContext' are incompatible.
                  Type 'import("node_modules/@sentry/types/types/scope").CaptureContext | undefined' is not assignable to type 'node_modules/@sentry/integrations/node_modules/@sentry/types/types/scope").CaptureContext | undefined'.
                    Type 'Scope' is not assignable to type 'CaptureContext | undefined'.

26     integrations: [new RewriteFrames({ root: '/' })],
                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

support for artifact bundles (release-based sourcemap uploading is deprecated)

It seems that Sentry has deprecated the release-based sourcemap uploading system used by toucan-js, and instead switched to a new system called "artifact bundles".

Unfortunately, it seems that toucan doesn't support this system yet.

At minimum (but I believe there is more to do as well), it looks like we need to use sentry version 7.47.0 โ€” this library is currently using 7.43.0.

Is this something you plan to support?

CleanShot 2023-06-07 at 17 12 18@2x

Allow instantiating Toucan before the request arrives

Hello again.

So I've using Toucan for a while in a couple of Cloudflare Workers projects now and have been wondering if we could change it so that I could instantiate the instance only once in the global context and reuse it for every request, like this:

type Handler = (req: Request) => Response | Promise<Response>;

declare const SENTRY_DSN: string;

const sentry = new Toucan({ dsn: SENTRY_DSN });

async function catchErrors(event: FetchEvent, handler: Handler): Promise<Response> {
  try {
    return await handler(event.request);
  } catch (err) {
    sentry.captureException(err, event);

    return new Response(null, { status: 500 });
  }
}

Of course, this would be a breaking change, so another idea I had was to make an extends method:

type Handler = (req: Request) => Response | Promise<Response>;

declare const SENTRY_DSN: string;

const baseSentry = new Toucan({ dsn: SENTRY_DSN });

async function catchErrors(event: FetchEvent, handler: Handler): Promise<Response> {
  const sentry = baseSentry.extend({ event });

  try {
    return await handler(event.request);
  } catch (err) {
    sentry.captureException(err, event);

    return new Response(null, { status: 500 });
  }
}

These ways we could define defaults and avoid instantiating extra objects at every request, but since Toucan's constructor requires the FetchEvent, neither of these options are possible right now.

Missing documentation for setRequestBody

I'm trying to read the documentation in order to attach the body of the request when an error happens.
This seems to be possible with setRequestBody, but the docs are clear at all about how to use said option.

Is that a boolean value? Is it a function? Should I call it (and how?)

Clarify waitUntil <> ES Modules API

Thanks for building this library!

#67 added support for modules, but it looks like it still depends on FetchEvent.waitUntil:

toucan-js/src/index.ts

Lines 197 to 202 in 44478b2

// This is to maintain backwards compatibility for 'event' option. When we remove it, all this complex logic can go away.
if ("context" in this.options) {
this.options.context.waitUntil(this.reportException(event, exception));
} else {
this.options.event.waitUntil(this.reportException(event, exception));
}

Since modules only receive a request object, and no fetch event, this causes an exception (can replicate with debug mode):

toucan-js: TypeError: Cannot read property 'waitUntil' of undefined

You can cheat a bit and provide a dummy function in context, but this won't do anything to tell the runtime to extend the lifetime of the promise, and you end up waiting for exception handling to complete before generating a response:

    const sentry = new Toucan({
      dsn: <DSN>,
      request,
      context: {
        waitUntil: async (cb) => await cb(),
      }
    });

Maybe I'm missing something here? Happy to contribute if there's something actionable here but I haven't found it.

Error building basic example

When trying to build the basic example, I get the following error:

โˆด yarn build
yarn run v1.22.19
$ wrangler publish --dry-run --outdir=dist
 โ›…๏ธ wrangler 2.5.0 (update available 2.6.2)
-----------------------------------------------------

โœ˜ [ERROR] Could not resolve "toucan-js"

    src/index.ts:1:23:
      1 โ”‚ import { Toucan } from 'toucan-js';
        โ•ต                        ~~~~~~~~~~~

  You can mark the path "toucan-js" as external to exclude it from the bundle, which will remove this error.


โœ˜ [ERROR] Build failed with 1 error:

  src/index.ts:1:23: ERROR: Could not resolve "toucan-js"


error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

I had assumed the build task would be configured to handle bundling. Is this not the case?

Toucan should import needed types from `@cloudflare/workers-types`

It looks like Toucan uses /// <reference types="@cloudflare/workers-types" /> to reference the ambient types for Cloudflare Workers. Unfortunately, that means that those types are included in any code that imports toucan-js, which isn't always the right behaviour. Specifically, I ran into an incompatibility between the latest compatibility date version of the types (@cloudflare/workers-types/experimental), and the oldest (which is what Toucan includes by default).

I think the fix will be to import the needed types from @cloudflare/workers-types when used in toucan-js.

Here is the diff that solved my problem:

diff --git a/node_modules/toucan-js/dist/transports/types.d.ts b/node_modules/toucan-js/dist/transports/types.d.ts
index 1503db4..3669365 100644
--- a/node_modules/toucan-js/dist/transports/types.d.ts
+++ b/node_modules/toucan-js/dist/transports/types.d.ts
@@ -1,4 +1,3 @@
-/// <reference types="@cloudflare/workers-types" />
 import type { BaseTransportOptions } from '@sentry/types';
 import type { Context } from '../types';
 export type FetchTransportOptions = BaseTransportOptions & {
diff --git a/node_modules/toucan-js/dist/types.d.ts b/node_modules/toucan-js/dist/types.d.ts
index d7bd18b..061aa19 100644
--- a/node_modules/toucan-js/dist/types.d.ts
+++ b/node_modules/toucan-js/dist/types.d.ts
@@ -1,4 +1,3 @@
-/// <reference types="@cloudflare/workers-types" />
 import type { ClientOptions, Options as CoreOptions } from '@sentry/types';
 import type { RequestDataOptions } from './integrations';
 import type { FetchTransportOptions } from './transports';

Worker calling `response.clone()`

I'm seeing this in my logs. Any thoughts?

Your worker called response.clone(), but did not read the body of both clones. This is wasteful, as it forces the system to buffer the entire response body in memory, rather than streaming it through. This may cause your worker to be unexpectedly terminated for going over the memory limit. If you only meant to copy the response headers and metadata (e.g. in order to be able to modify them), use `new Response(response.body, response)` instead.

Cannot import type Options

Hi,

I am unable to import the type Options use in constructor of class Toucan.
Is there a way of importing it?

Thanks for making this lib !

Source maps still don't seem to be working

Followed the guide in the README and the thread but I'm still getting errors when attempting to link to my source map.

Screen Shot 2021-01-12 at 8 34 49 PM

Maybe I'm missing or misunderstanding something still?

addEventListener('fetch', (event) => {
  const sentry = new Toucan({
    dsn: SENTRY_DSN,
    event,
    environment: 'development',
    release: 'pre-release',
    allowedCookies: /(.*)/,
    allowedHeaders: /(.*)/,
    allowedSearchParams: /(.*)/,
    rewriteFrames: {
      root: '/'
    }
  })

  event.respondWith(handleRequest(event, sentry))
})
const SentryWebpackPlugin = require('@sentry/webpack-plugin')

module.exports = {
  entry: './src/index.js',
  target: 'webworker',
  devtool: 'cheap-module-source-map',
  node: {
    fs: 'empty'
  },
  plugins: [
    new SentryWebpackPlugin({
      authToken: 'abc123',
      release: 'pre-release',
      org: 'abc',
      project: '123',
      include: './dist',
      urlPrefix: '/',
    }),
  ],
}

source map don't work anymore ?

Hi I'm using one of the example provided in toucan-js/example specifically wrangler-basic. I was expecting to see the error with source map in sentry dash but I only get a stack trace. I can confirm the files have been uploaded but it seems they are not linked.
has anything changed since the creation of the example to make it work.
I ran build and then deploy i got no error or warning in the terminal.

scheduled waitUntil() don't report anything (maybe a typo in the README)

From the README, passing a function to context.waitUntil don't seem to work.

export default {
    async scheduled(controller: Controller, env: Env, context: Context) {
        //...
        context.waitUntil(async () => {
            try {
                // Your code
            } catch (err) {
                sentry.captureException(err);
            }
        });
    },
}

From Cloudflare Documentation / ScheduledEvent / Syntax: Module Worker, the function passed to context.waitUntil must be called

export default {
    async scheduled(event, env, ctx) {
        ctx.waitUntil(doSomeTaskOnASchedule());
    },
};

so the code that works:

export default {
    async scheduled(controller: Controller, env: Env, context: Context) {
        //...
        context.waitUntil((async () => {
            try {
                // Your code
            } catch (err) {
                sentry.captureException(err);
            }
        })());
    },
}

  • module (.mjs)
  • wrangler 2.1.6
  • node: v18.9.0
  • OS: ArchLinux

Any info on source-maps?

Thanks for the lib, looks great. Wondering if you have any advice on source maps or legible stack traces in the Sentry Dashboar?

startTransaction() returns null

Hi,

why is startTransaction() returning null in this case? (sentry object works and is used in my app):

      const sentry = new Toucan({
         dsn: env.SENTRY_DSN,
         context,
         request,
      });

      const transaction = sentry.startTransaction({
         name: "Some Name",
      });

Do i need to import something besides the main Toucan package?

Thanks.

Any plans to upgrade toucan-js to support latest features?

Sentry has released a few features, namely performance monitoring and metrics (beta), that would be a great addition in the Cloudflare Workers environment.

Do you have any plans to bring these features to Toucan or merge automatic PRs for newer Sentry package versions?

configureScope does not work

Calling configureScope seems to do absolutely nothing. Putting a log inside the callback results in nothing being logged.

Looking at the source, I don't see configureScope implemented at all, but I do see that the whole class is wrapped in a Proxy, which I suspect is suppressing errors you'd normally get for calling an undefined method.

SvelteKit

Has anyone got Toucan to work with SvelteKit on Cloudflare Pages?

EDIT

For now I just hooked Toucan up in src/hooks.server.ts

import type { HandleServerError } from '@sveltejs/kit';
import { Toucan } from 'toucan-js';

// use handleError to report errors during server-side data loading
export const handleError: HandleServerError = ({ error, event }) => {
	const sentry = new Toucan({
		dsn: '<DSN>',
		request: event.request
	});

	sentry.captureException(error);

	return {
		message: error instanceof Error && 'message' in error ? error.message : String(error)
	};
};

Transactions and spans not being propagated - bug or as intended?

Hi,
I'm trying to write middleware that uses Sentry for distributed tracing through Toucan for an Astro site with Cloudflare Workers SSR.

As is, the only reporting I'm seeing is individual event propagation via e.g. captureException. With the code as-is, these errors are unconnected to any individual trace even though the Sentry-Trace header is being sent to the server side (and is on the same domain so doesn't have any CORS problems).

I'm able to use the relatively new propagationContextFromHeaders utility function like so:

import { propagationContextFromHeaders } from "@sentry/utils";
export const onRequest = defineMiddleware(async (context, next) => {
// ...
  const propagationContext = propagationContextFromHeaders(
    context.request.headers.get("sentry-trace") ?? undefined,
    context.request.headers.get("baggage")
  );
  // @ts-expect-error because of minor mismatch in propagationContext type
  sentry.getScope().setPropagationContext(propagationContext);

And then errors will end up logged and associated with the trace id initiated on the client side, but with no information beyond the fact the error happened. However, even when I add the Transaction integration via integrations: [new Transaction()], in the Toucan constructor, I don't see any sentry reporting about the spans and or transaction that the individual trace was a part of.

I understand that performance timing / Date.now() are inaccurate on the CF Worker platform, but I am wondering whether there is a way to get Toucan to still report the (inaccurate) timestamps and transactions/spans. I tried creating new transactions/child spans, running .finish(), and still don't see anything reported, either using a beforeSend hook in the Toucan constructor or on the Sentry dashboard.

Is there a way to get those reported? And would a PR adding the propagation context by default in Toucan be desirable? Thanks!

Uploading source maps with the modules syntax

Hey there, great work on the Sentry client, I love it ๐Ÿ™‡

I have more of a question because I can't find anywhere else to ask. I switched to module syntax for Workers and I have trouble uploading source maps. I use Webpack with experiments.outputModule to generate the code. Here's my webpack.config.js:

if (process.env.SENTRY_AUTH_TOKEN) {
  plugins.push(
    new SentryWebpackPlugin({
      authToken: process.env.SENTRY_AUTH_TOKEN,
      org: 'random-org',
      project: 'random-project',
      release: process.env.RELEASE,
      include: './dist',
      urlPrefix: '/',
      ignore: ['node_modules']
    })
  )
}

module.exports = {
  output: {
    filename: `worker.mjs`,
    libraryTarget: 'module',
    path: path.join(__dirname, 'dist')
  },
  mode,
  resolve: {
    extensions: ['.ts', '.js']
  },
  devtool: 'source-map',
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        loader: 'ts-loader',
      }
    ]
  },
  experiments: {
    outputModule: true
  },
  plugins
}

I get the worker.mjs.map but when it is uploaded to Sentry it doesn't 'connect' properly to the stack trace I receive. Did anyone get source maps working with the modules syntax and Sentry so far?

Thanks for all the work here ๐Ÿ™‡

How do I use toucan-js with Sentry Performance/Tracing

Hi! I want to use toucan-js for collecting tracing data with my cloudflare workers application.

I have set up the tracesSampleRate when new Toucan({<options>}), but it does not work, no data on the sentry performance panel appeared.

What should I do to use toucan with tracing correctly?

Thank in advance!

dsn vs transportOptions.dsn in options?

In Toucan options there are now two places for DSN:

  • dsn (has star in README, optional in code)
  • transportOptions.dsn (described as string in README, a DsnLike from @sentry/types in code)

Both can only be set at initialization. What is the difference between these options? Looking at the code, it seems like transportOptions.dsn is used to rewrite options.dsn, the purpose behind this is unclear and not documented.

Durable Objects and modules

Just wanted to give a heads up that Durable Objects and standard Workers written as modules is on my radar, but there are still many moving pieces in BETA and so I don't want to rush this. I'm expecting breaking changes in how toucan-js is going to consume event properties like waitUntil or request in mjs world.

Timestamps sent with year 2077

The following repro will send timestamps with year 2077 in Self Hosted:
In Sentry.io the transaction is dropped (I assume because it is 53 years in the future!)

import { Toucan } from "toucan-js";
import { addTracingExtensions } from '@sentry/core';

export interface Env {
  SENTRY_DSN: string;
}

export default {
  async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
    addTracingExtensions();
    const sentry = new Toucan({
      dsn: env.SENTRY_DSN,
      release: '1.0.0',
      context: ctx,
      request,
      sampleRate: 1.0,
      tracesSampleRate: 1.0,
      enableTracing: true,
    });

    const transaction = sentry.startTransaction({ name: 'test', description: 'test', op: 'http.server', metadata: { source: 'route' } });
    try {
      await fetch('https://google.com'); // just to cause some IO
      return new Response('Hello world!');
    } catch (e) {
      sentry.captureException(e);

      return new Response('Something went wrong! Team has been notified.', {
        status: 500,
      });
    } finally {
      transaction.finish();
    }
  },
};

Passing startTimestamp and endTimestamp explicitly via performance.now()/1000 it works as expected.
I have raised this issue with sentry, but they asked me to follow up here.
I am sorry if this is not related to this repo, but it could be worth being aware.

Sentry Hub has been deprecated in since version 7.110.0

According to these docs the Hub object that Toucan's main class extends has been deprecated since Sentry v7.110.0

https://docs.sentry.io/platforms/javascript/migration/v7-to-v8/v7-deprecations/#deprecate-hub

I'm using Hono with @hono/sentry that integrates Toucan and the following both yield deprecation warnings

c.get('sentry').setContext({ ... })
c.get('sentry').captureException(err)

How can we access the new Sentry object? Should Toucan be extending the new Sentry object? Should we use @sentry/node?

Add support for sampling

The official Sentry documentation states:

sampleRate
Configures the sample rate as a percentage of events to be sent in the range of 0.0 to 1.0. The default is 1.0 which means that 100% of events are sent. If set to 0.1 only 10% of events will be sent. Events are picked randomly.

It would be very valuable to make this a configurable option in toucan-js.

`setFingerprint` no longer available in v3?

Hi,
I was using setFingerprint function to create a customer identifier for errors, but it seems like v3 removed this option (and it's not mentioned in the changelog?)

Is there an alternative usage for setting the fingerprint of an exception reported?

Thanks!

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Detected dependencies

github-actions
.github/workflows/release.yml
  • actions/checkout v4
  • actions/setup-node v4
  • changesets/action v1
.github/workflows/test.yml
  • actions/checkout v4
  • actions/setup-node v4
npm
package.json
  • @changesets/cli ^2.25.2
  • prettier ^3.0.0
  • prettier-plugin-organize-imports ^4.0.0
  • turbo ^1.6.3
  • typescript 5.1.6
  • node >=16.18
packages/config-jest/package.json
  • ts-jest 29.1.1
  • jest 29.6.1
  • miniflare 3.20240701.0
  • jest-environment-miniflare 2.11.0
packages/config-typescript/package.json
  • @cloudflare/workers-types 4.20230307.0
packages/eslint-config-base/package.json
  • eslint ^8.29.0
  • eslint-config-prettier ^9.0.0
  • eslint-config-turbo ^1.0.0
  • @typescript-eslint/eslint-plugin ^6.0.0
  • @typescript-eslint/parser ^6.0.0
packages/toucan-js/package.json
  • @sentry/core 8.9.2
  • @sentry/utils 8.9.2
  • @sentry/types 8.9.2
  • @rollup/plugin-commonjs 26.0.1
  • @rollup/plugin-node-resolve 15.1.0
  • @rollup/plugin-replace 5.0.2
  • rollup 3.26.3
  • rollup-plugin-typescript2 0.35.0
  • @types/jest 29.5.3
  • jest 29.6.1
  • miniflare 3.20240701.0
  • jest-environment-miniflare 2.10.0
  • ts-jest 29.1.1
  • ts-node 10.9.1

  • Check this box to trigger a request for Renovate to run again on this repository

Possible to customize fetcher?

I'd like to use my own transport fetch-like mechansim instead of global fetch. Would a PR making a change here be acceptable so that the fetch function can be injected as a transport option?

Send Error.cause as a chained exception to Sentry

We're re-throwing an error to add context and setting the cause optional property to preserve the original error
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/cause

It'd be great to see the cause show up in Sentry as a part of the error info. It looks like sending the error.cause as an additional exception in the list might be the way to go https://develop.sentry.dev/sdk/event-payloads/exception/#examples

Sessions/session data not being sent to Sentry?

It looks like Toucan is not sending sessions/session data to Sentry. I see no session being recorded after I ran the worker several times:

no-sessions

Here's the worker TypeScript code:

import { Toucan } from 'toucan-js';

export interface Env {}

export default {
	async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
		const sentry = new Toucan({
			dsn: 'ADD_YOUR_DSN_HERE',
			context: ctx,
			request,
			release: 'fetch',
		});

		try {
			// throw new Error('This is a test error');
			return new Response('Hello World!');
		} catch (error) {
			sentry.captureException(error);
			return new Response('Internal Server Error', { status: 500 });
		}
	},
};

Is this a bug?
Or, perhaps, a feature missing from Toucan?
Or, perhaps, I am missing something?

Thanks in advance ๐Ÿ‘

Usage with Next.js on Cloudflare via next-on-pages?

Hi! I appreciate the work you've put into building this library and I'm actively using it on Cloudflare Workers.

I was wondering if there are any instructions on how to set it up with next-on-pages as well?

Sentry performance monitoring

Hey there,

thanks for the great library! I've trying to use sentry performance tracking https://docs.sentry.io/platforms/node/performance/ on cf workers for quite some time, but couldn't get it working cause of the timer blocking.
I've read of the partnering with sentry through this library on the cf blog and wanted to ask if it's intended to get the performance monitoring somehow working?

Thanks

Alex

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.