Skip to content

Commit

Permalink
Add sendError helper to Tracer object
Browse files Browse the repository at this point in the history
This new helper allows you to track an error isolatedly without a span
present in the context.

An error is passed and a callback with a span is provided to add desired
metadata to it.
  • Loading branch information
luismiramirez committed Sep 30, 2021
1 parent 1f182a4 commit 96df8a4
Show file tree
Hide file tree
Showing 11 changed files with 104 additions and 23 deletions.
34 changes: 17 additions & 17 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"packages/*"
],
"devDependencies": {
"@appsignal/types": "^2.1.3",
"@appsignal/types": "^2.1.5",
"@types/jest": "^26.0.19",
"husky": "^4.3.6",
"jest": "^26.6.3",
Expand Down
2 changes: 1 addition & 1 deletion packages/apollo-server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"types": "dist/index",
"license": "MIT",
"dependencies": {
"@appsignal/types": "^2.1.3",
"@appsignal/types": "^2.1.5",
"apollo-server-plugin-base": "^0.10.3",
"tslib": "^2.0.3"
},
Expand Down
2 changes: 1 addition & 1 deletion packages/express/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"types": "dist/index",
"license": "MIT",
"dependencies": {
"@appsignal/types": "^2.1.3",
"@appsignal/types": "^2.1.5",
"tslib": "^2.0.3"
},
"peerDependencies": {
Expand Down
2 changes: 1 addition & 1 deletion packages/koa/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"types": "dist/index",
"license": "MIT",
"dependencies": {
"@appsignal/types": "^2.1.3",
"@appsignal/types": "^2.1.5",
"shimmer": "^1.2.1",
"tslib": "^2.0.3"
},
Expand Down
2 changes: 1 addition & 1 deletion packages/nextjs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"types": "dist/index",
"license": "MIT",
"dependencies": {
"@appsignal/types": "^2.1.3",
"@appsignal/types": "^2.1.5",
"tslib": "^2.0.3"
},
"peerDependencies": {
Expand Down
20 changes: 20 additions & 0 deletions packages/nodejs/.changesets/add-senderror-helper-to-tracer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
bump: "patch"
---

Add sendError helper to Tracer object.

This new helper allows you to track an error separately from any other span
inside the current context. Or use it to set up in your own error handling to
report errors in a catch-statement if no performance monitoring is needed.

```js
try {
// Do complex stuff
} catch (error) {
appsignal.tracer().sendError(error, span => {
span.setName("daily.task"); // Set a recognizable action name
span.set("user_id", user_id); // Set custom tags
});
}
```
2 changes: 1 addition & 1 deletion packages/nodejs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
},
"dependencies": {
"@appsignal/core": "^1.1.4",
"@appsignal/types": "^2.1.3",
"@appsignal/types": "^2.1.5",
"require-in-the-middle": "^5.1.0",
"semver": "^7.3.4",
"shimmer": "^1.2.1",
Expand Down
42 changes: 42 additions & 0 deletions packages/nodejs/src/__tests__/tracer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,48 @@ describe("Tracer", () => {
})
})

describe(".sendError()", () => {
const err = new Error("FooBarError")

it("works without metadata callback", () => {
tracer.sendError(err)
})

it("uses a RootSpan", done => {
tracer.sendError(err, rootSpan => {
expect(rootSpan).toBeInstanceOf(RootSpan)

return done()
})
})

it("assigns metadata to the span if needed", done => {
tracer.sendError(err, rootSpan => {
rootSpan.setName("foo")
rootSpan.setCategory("bar")
rootSpan.set("pod", 42)

const rootSpanData = JSON.parse(rootSpan.toJSON())

expect(rootSpanData.name).toEqual("foo")
expect(rootSpanData.attributes["appsignal:category"]).toEqual("bar")
expect(rootSpanData.attributes.pod).toEqual(42)

return done()
})
})

it("adds the given error to the span", done => {
tracer.sendError(err, rootSpan => {
const rootSpanData = JSON.parse(rootSpan.toJSON())

expect(rootSpanData.error.message).toEqual("FooBarError")

return done()
})
})
})

describe("Span instrumentation", () => {
it("can instrument a function (async)", async done => {
const rootSpan = tracer.createSpan().setName(name)
Expand Down
4 changes: 4 additions & 0 deletions packages/nodejs/src/noops/tracer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ export class NoopTracer implements Tracer {
return new NoopSpan()
}

public sendError<T>(error: Error, fn: (s: NodeSpan) => T): void {
return
}

public withSpan<T>(span: NodeSpan, fn: (s: NodeSpan) => T): T {
return fn(span)
}
Expand Down
15 changes: 15 additions & 0 deletions packages/nodejs/src/tracer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,21 @@ export class BaseTracer implements Tracer {
return activeRootSpan
}

/**
* Sends an error in a newly created `RootSpan` that will be closed after
* the given error is added to it.
*
* The created `RootSpan` is passed as the single argument to the given function.
* This allows you to add arbitrary metadata to it.
*/
public sendError<T>(error: Error, fn?: (s: NodeSpan) => T): void {
const rootSpan = new RootSpan()

rootSpan.setError(error)
if (fn && typeof fn === "function") fn(rootSpan)
rootSpan.close()
}

/**
* Executes a given function within the context of a given `Span`. When the
* function has finished executing, any value returned by the given function
Expand Down

0 comments on commit 96df8a4

Please sign in to comment.