mirror of
https://fast.feibisi.com/https://github.com/parcelvoy/platform.git
synced 2025-09-01 12:26:08 +08:00
Adds error handling with third parties (#113)
This commit is contained in:
parent
a035276986
commit
dcb41b8cca
10 changed files with 313 additions and 5 deletions
199
apps/platform/package-lock.json
generated
199
apps/platform/package-lock.json
generated
|
@ -13,12 +13,16 @@
|
|||
"@aws-sdk/client-sns": "^3.121.0",
|
||||
"@aws-sdk/client-sqs": "^3.171.0",
|
||||
"@aws-sdk/lib-storage": "^3.171.0",
|
||||
"@bugsnag/js": "^7.20.0",
|
||||
"@bugsnag/plugin-koa": "^7.19.0",
|
||||
"@koa/cors": "^3.3.0",
|
||||
"@koa/router": "^11.0.1",
|
||||
"@ladjs/country-language": "^1.0.3",
|
||||
"@node-saml/node-saml": "github:node-saml/node-saml",
|
||||
"@rxfork/sqs-consumer": "^6.0.0",
|
||||
"@segment/analytics-node": "^1.0.0-beta.23",
|
||||
"@sentry/node": "^7.46.0",
|
||||
"@sentry/utils": "^7.46.0",
|
||||
"ajv": "^8.11.0",
|
||||
"ajv-errors": "^3.0.0",
|
||||
"ajv-formats": "^2.1.1",
|
||||
|
@ -2143,6 +2147,69 @@
|
|||
"integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@bugsnag/browser": {
|
||||
"version": "7.20.0",
|
||||
"resolved": "https://registry.npmjs.org/@bugsnag/browser/-/browser-7.20.0.tgz",
|
||||
"integrity": "sha512-LzZWI6q5cWYQSXvfJDcSl287d2xXESVn0L20lK+K5nwo/jXcK9IVZr9L+CYZ40HVXaC9jOmQbqZ18hsbO2QNIw==",
|
||||
"dependencies": {
|
||||
"@bugsnag/core": "^7.19.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@bugsnag/core": {
|
||||
"version": "7.19.0",
|
||||
"resolved": "https://registry.npmjs.org/@bugsnag/core/-/core-7.19.0.tgz",
|
||||
"integrity": "sha512-2KGwdaLD9PhR7Wk7xPi3jGuGsKTatc/28U4TOZIDU3CgC2QhGjubwiXSECel5gwxhZ3jACKcMKSV2ovHhv1NrA==",
|
||||
"dependencies": {
|
||||
"@bugsnag/cuid": "^3.0.0",
|
||||
"@bugsnag/safe-json-stringify": "^6.0.0",
|
||||
"error-stack-parser": "^2.0.3",
|
||||
"iserror": "0.0.2",
|
||||
"stack-generator": "^2.0.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@bugsnag/cuid": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@bugsnag/cuid/-/cuid-3.0.2.tgz",
|
||||
"integrity": "sha512-cIwzC93r3PQ/INeuwtZwkZIG2K8WWN0rRLZQhu+mr48Ay+i6sEki4GYfTsflse7hZ1BeDWrNb/Q9vgY3B31xHQ=="
|
||||
},
|
||||
"node_modules/@bugsnag/js": {
|
||||
"version": "7.20.0",
|
||||
"resolved": "https://registry.npmjs.org/@bugsnag/js/-/js-7.20.0.tgz",
|
||||
"integrity": "sha512-lhUUSOveE8fP10RagAINqBmuH+eoOpyUOiTN1WRkjHUevWG0LZjRRUWEGN3AA+ZyTphmC6ljd2qE3/64qfOSGQ==",
|
||||
"dependencies": {
|
||||
"@bugsnag/browser": "^7.20.0",
|
||||
"@bugsnag/node": "^7.19.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@bugsnag/node": {
|
||||
"version": "7.19.0",
|
||||
"resolved": "https://registry.npmjs.org/@bugsnag/node/-/node-7.19.0.tgz",
|
||||
"integrity": "sha512-c4snyxx5d/fsMogmgehFBGc//daH6+4XCplia4zrEQYltjaQ+l8ud0dPx623DgJl/2j1+2zlRc7y7IHSd7Gm5w==",
|
||||
"dependencies": {
|
||||
"@bugsnag/core": "^7.19.0",
|
||||
"byline": "^5.0.0",
|
||||
"error-stack-parser": "^2.0.2",
|
||||
"iserror": "^0.0.2",
|
||||
"pump": "^3.0.0",
|
||||
"stack-generator": "^2.0.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@bugsnag/plugin-koa": {
|
||||
"version": "7.19.0",
|
||||
"resolved": "https://registry.npmjs.org/@bugsnag/plugin-koa/-/plugin-koa-7.19.0.tgz",
|
||||
"integrity": "sha512-zvzOMf1oXgO1hi0bQti+khFn4D32EfMv6W3Vc65+wcSGSFaMxuPJSE8sdOJqE6gFj2ANhCpHk8UvzlMAzRODSw==",
|
||||
"dependencies": {
|
||||
"iserror": "^0.0.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@bugsnag/core": "^7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@bugsnag/safe-json-stringify": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@bugsnag/safe-json-stringify/-/safe-json-stringify-6.0.0.tgz",
|
||||
"integrity": "sha512-htzFO1Zc57S8kgdRK9mLcPVTW1BY2ijfH7Dk2CeZmspTWKdKqSo1iwmqrq2WtRjFlo8aRZYgLX0wFrDXF/9DLA=="
|
||||
},
|
||||
"node_modules/@cspotcode/source-map-support": {
|
||||
"version": "0.8.1",
|
||||
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
|
||||
|
@ -2993,6 +3060,91 @@
|
|||
"url": "https://ko-fi.com/killymxi"
|
||||
}
|
||||
},
|
||||
"node_modules/@sentry-internal/tracing": {
|
||||
"version": "7.46.0",
|
||||
"resolved": "https://registry.npmjs.org/@sentry-internal/tracing/-/tracing-7.46.0.tgz",
|
||||
"integrity": "sha512-KYoppa7PPL8Er7bdPoxTNUfIY804JL7hhOEomQHYD22rLynwQ4AaLm3YEY75QWwcGb0B7ZDMV+tSumW7Rxuwuw==",
|
||||
"dependencies": {
|
||||
"@sentry/core": "7.46.0",
|
||||
"@sentry/types": "7.46.0",
|
||||
"@sentry/utils": "7.46.0",
|
||||
"tslib": "^1.9.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/@sentry-internal/tracing/node_modules/tslib": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
||||
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
|
||||
},
|
||||
"node_modules/@sentry/core": {
|
||||
"version": "7.46.0",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.46.0.tgz",
|
||||
"integrity": "sha512-BnNHGh/ZTztqQedFko7vb2u6yLs/kWesOQNivav32ZbsEpVCjcmG1gOJXh2YmGIvj3jXOC9a4xfIuh+lYFcA6A==",
|
||||
"dependencies": {
|
||||
"@sentry/types": "7.46.0",
|
||||
"@sentry/utils": "7.46.0",
|
||||
"tslib": "^1.9.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/@sentry/core/node_modules/tslib": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
||||
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
|
||||
},
|
||||
"node_modules/@sentry/node": {
|
||||
"version": "7.46.0",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/node/-/node-7.46.0.tgz",
|
||||
"integrity": "sha512-+GrgJMCye2WXGarRiU5IJHCK27xg7xbPc2XjGojBKbBoZfqxVAWbXEK4bnBQgRGP1pCmrU/M6ZhVgR3dP580xA==",
|
||||
"dependencies": {
|
||||
"@sentry-internal/tracing": "7.46.0",
|
||||
"@sentry/core": "7.46.0",
|
||||
"@sentry/types": "7.46.0",
|
||||
"@sentry/utils": "7.46.0",
|
||||
"cookie": "^0.4.1",
|
||||
"https-proxy-agent": "^5.0.0",
|
||||
"lru_map": "^0.3.3",
|
||||
"tslib": "^1.9.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/@sentry/node/node_modules/tslib": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
||||
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
|
||||
},
|
||||
"node_modules/@sentry/types": {
|
||||
"version": "7.46.0",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.46.0.tgz",
|
||||
"integrity": "sha512-2FMEMgt2h6u7AoELhNhu9L54GAh67KKfK2pJ1kEXJHmWxM9FSCkizjLs/t+49xtY7jEXr8qYq8bV967VfDPQ9g==",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/@sentry/utils": {
|
||||
"version": "7.46.0",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.46.0.tgz",
|
||||
"integrity": "sha512-elRezDAF84guMG0OVIIZEWm6wUpgbda4HGks98CFnPsrnMm3N1bdBI9XdlxYLtf+ir5KsGR5YlEIf/a0kRUwAQ==",
|
||||
"dependencies": {
|
||||
"@sentry/types": "7.46.0",
|
||||
"tslib": "^1.9.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/@sentry/utils/node_modules/tslib": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
||||
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
|
||||
},
|
||||
"node_modules/@sinclair/typebox": {
|
||||
"version": "0.24.51",
|
||||
"resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz",
|
||||
|
@ -4309,6 +4461,14 @@
|
|||
"node": ">=10.16.0"
|
||||
}
|
||||
},
|
||||
"node_modules/byline": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/byline/-/byline-5.0.0.tgz",
|
||||
"integrity": "sha512-s6webAy+R4SR8XVuJWt2V2rGvhnrhxN+9S15GNuTK3wKPOXFF6RNc+8ug2XhH+2s4f+uudG4kUVYmYOQWL2g0Q==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/bytes": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
|
||||
|
@ -4594,6 +4754,14 @@
|
|||
"integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/cookie": {
|
||||
"version": "0.4.2",
|
||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz",
|
||||
"integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/cookies": {
|
||||
"version": "0.8.0",
|
||||
"resolved": "https://registry.npmjs.org/cookies/-/cookies-0.8.0.tgz",
|
||||
|
@ -4990,6 +5158,14 @@
|
|||
"is-arrayish": "^0.2.1"
|
||||
}
|
||||
},
|
||||
"node_modules/error-stack-parser": {
|
||||
"version": "2.1.4",
|
||||
"resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.1.4.tgz",
|
||||
"integrity": "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==",
|
||||
"dependencies": {
|
||||
"stackframe": "^1.3.4"
|
||||
}
|
||||
},
|
||||
"node_modules/es-abstract": {
|
||||
"version": "1.21.1",
|
||||
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.1.tgz",
|
||||
|
@ -7038,6 +7214,11 @@
|
|||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/iserror": {
|
||||
"version": "0.0.2",
|
||||
"resolved": "https://registry.npmjs.org/iserror/-/iserror-0.0.2.tgz",
|
||||
"integrity": "sha512-oKGGrFVaWwETimP3SiWwjDeY27ovZoyZPHtxblC4hCq9fXxed/jasx+ATWFFjCVSRZng8VTMsN1nDnGo6zMBSw=="
|
||||
},
|
||||
"node_modules/isexe": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
||||
|
@ -8266,6 +8447,11 @@
|
|||
"resolved": "https://registry.npmjs.org/long-timeout/-/long-timeout-0.1.1.tgz",
|
||||
"integrity": "sha512-BFRuQUqc7x2NWxfJBCyUrN8iYUYznzL9JROmRz1gZ6KlOIgmoD+njPVbb+VNn2nGMKggMsK79iUNErillsrx7w=="
|
||||
},
|
||||
"node_modules/lru_map": {
|
||||
"version": "0.3.3",
|
||||
"resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz",
|
||||
"integrity": "sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ=="
|
||||
},
|
||||
"node_modules/lru-cache": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
|
||||
|
@ -10035,6 +10221,14 @@
|
|||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/stack-generator": {
|
||||
"version": "2.0.10",
|
||||
"resolved": "https://registry.npmjs.org/stack-generator/-/stack-generator-2.0.10.tgz",
|
||||
"integrity": "sha512-mwnua/hkqM6pF4k8SnmZ2zfETsRUpWXREfA/goT8SLCV4iOFa4bzOX2nDipWAZFPTjLvQB82f5yaodMVhK0yJQ==",
|
||||
"dependencies": {
|
||||
"stackframe": "^1.3.4"
|
||||
}
|
||||
},
|
||||
"node_modules/stack-utils": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz",
|
||||
|
@ -10056,6 +10250,11 @@
|
|||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/stackframe": {
|
||||
"version": "1.3.4",
|
||||
"resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz",
|
||||
"integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw=="
|
||||
},
|
||||
"node_modules/standard-as-callback": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/standard-as-callback/-/standard-as-callback-2.1.0.tgz",
|
||||
|
|
|
@ -7,12 +7,16 @@
|
|||
"@aws-sdk/client-sns": "^3.121.0",
|
||||
"@aws-sdk/client-sqs": "^3.171.0",
|
||||
"@aws-sdk/lib-storage": "^3.171.0",
|
||||
"@bugsnag/js": "^7.20.0",
|
||||
"@bugsnag/plugin-koa": "^7.19.0",
|
||||
"@koa/cors": "^3.3.0",
|
||||
"@koa/router": "^11.0.1",
|
||||
"@ladjs/country-language": "^1.0.3",
|
||||
"@node-saml/node-saml": "github:node-saml/node-saml",
|
||||
"@rxfork/sqs-consumer": "^6.0.0",
|
||||
"@segment/analytics-node": "^1.0.0-beta.23",
|
||||
"@sentry/node": "^7.46.0",
|
||||
"@sentry/utils": "^7.46.0",
|
||||
"ajv": "^8.11.0",
|
||||
"ajv-errors": "^3.0.0",
|
||||
"ajv-formats": "^2.1.1",
|
||||
|
|
|
@ -13,12 +13,10 @@ export default class Api extends Koa {
|
|||
|
||||
this.proxy = process.env.NODE_ENV !== 'development'
|
||||
|
||||
app.error.attach(this)
|
||||
|
||||
this.use(koaBody())
|
||||
.use(cors())
|
||||
.use((ctx, next) => {
|
||||
ctx.state.app = this.app
|
||||
return next()
|
||||
})
|
||||
.use(serve('./public', {
|
||||
hidden: true,
|
||||
defer: true,
|
||||
|
|
|
@ -2,6 +2,7 @@ import loadDatabase, { Database } from './config/database'
|
|||
import loadQueue from './config/queue'
|
||||
import loadStorage from './config/storage'
|
||||
import loadAuth from './config/auth'
|
||||
import loadError, { logger } from './config/logger'
|
||||
import type { Env } from './config/env'
|
||||
import type Queue from './queue'
|
||||
import Storage from './storage'
|
||||
|
@ -9,7 +10,7 @@ import type Auth from './auth/Auth'
|
|||
import { uuid } from './utilities'
|
||||
import Api from './api'
|
||||
import Worker from './worker'
|
||||
import { logger } from './config/logger'
|
||||
import ErrorHandler from './error/ErrorHandler'
|
||||
|
||||
export default class App {
|
||||
private static $main: App
|
||||
|
@ -21,6 +22,10 @@ export default class App {
|
|||
}
|
||||
|
||||
static async init(env: Env): Promise<App> {
|
||||
|
||||
// Boot up error tracking
|
||||
const error = await loadError(env.error)
|
||||
|
||||
// Load & migrate database
|
||||
const database = await loadDatabase(env.db)
|
||||
|
||||
|
@ -39,6 +44,7 @@ export default class App {
|
|||
queue,
|
||||
auth,
|
||||
storage,
|
||||
error,
|
||||
)
|
||||
|
||||
return App.$main
|
||||
|
@ -56,6 +62,7 @@ export default class App {
|
|||
public queue: Queue,
|
||||
public auth: Auth,
|
||||
public storage: Storage,
|
||||
public error: ErrorHandler,
|
||||
) {
|
||||
this.#registered = {}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ import type { StorageConfig } from '../storage/Storage'
|
|||
import type { QueueConfig } from '../queue/Queue'
|
||||
import type { DatabaseConfig } from './database'
|
||||
import type { AuthConfig } from '../auth/Auth'
|
||||
import type { ErrorConfig } from '../error/ErrorHandler'
|
||||
|
||||
export type Runner = 'api' | 'worker'
|
||||
export interface Env {
|
||||
|
@ -14,6 +15,7 @@ export interface Env {
|
|||
port: number
|
||||
secret: string
|
||||
auth: AuthConfig
|
||||
error: ErrorConfig
|
||||
tracking: {
|
||||
linkWrap: boolean,
|
||||
deeplinkMirrorUrl: string | undefined,
|
||||
|
@ -107,6 +109,14 @@ export default (type?: EnvType): Env => {
|
|||
tokenLife: defaultTokenLife,
|
||||
}),
|
||||
}),
|
||||
error: driver<ErrorConfig>(process.env.ERROR_DRIVER, {
|
||||
bugsnag: () => ({
|
||||
apiKey: process.env.ERROR_BUGSNAG_API_KEY,
|
||||
}),
|
||||
sentry: () => ({
|
||||
dsn: process.env.ERROR_SENTRY_DSN,
|
||||
}),
|
||||
}),
|
||||
tracking: {
|
||||
linkWrap: (process.env.TRACKING_LINK_WRAP ?? 'true') === 'true',
|
||||
deeplinkMirrorUrl: process.env.TRACKING_DEEPLINK_MIRROR_URL,
|
||||
|
|
|
@ -1,7 +1,12 @@
|
|||
import pino from 'pino'
|
||||
import pretty from 'pino-pretty'
|
||||
import ErrorHandler, { ErrorConfig } from '../error/ErrorHandler'
|
||||
|
||||
// TODO: Check ENV and disable prettier for production
|
||||
export const logger = pino({
|
||||
level: process.env.LOG_LEVEL || 'warn',
|
||||
}, pretty({ colorize: true }))
|
||||
|
||||
export default async (config: ErrorConfig) => {
|
||||
return new ErrorHandler(config)
|
||||
}
|
||||
|
|
28
apps/platform/src/error/BugSnagProvider.ts
Normal file
28
apps/platform/src/error/BugSnagProvider.ts
Normal file
|
@ -0,0 +1,28 @@
|
|||
import { ErrorHandlerTypeConfig } from './ErrorHandler'
|
||||
import ErrorHandlingProvider from './ErrorHandlerProvider'
|
||||
import Koa from 'koa'
|
||||
import Bugsnag from '@bugsnag/js'
|
||||
import BugsnagPluginKoa from '@bugsnag/plugin-koa'
|
||||
|
||||
export interface BugSnagConfig extends ErrorHandlerTypeConfig {
|
||||
driver: 'bugsnag'
|
||||
apiKey: string
|
||||
}
|
||||
|
||||
export default class BugSnagProvider implements ErrorHandlingProvider {
|
||||
constructor(config: BugSnagConfig) {
|
||||
Bugsnag.start({
|
||||
apiKey: config.apiKey,
|
||||
logger: null,
|
||||
plugins: [BugsnagPluginKoa],
|
||||
})
|
||||
}
|
||||
|
||||
attach(api: Koa) {
|
||||
const middleware = Bugsnag.getPlugin('koa')
|
||||
if (middleware) {
|
||||
api.use(middleware.requestHandler)
|
||||
api.on('error', middleware.errorHandler)
|
||||
}
|
||||
}
|
||||
}
|
26
apps/platform/src/error/ErrorHandler.ts
Normal file
26
apps/platform/src/error/ErrorHandler.ts
Normal file
|
@ -0,0 +1,26 @@
|
|||
import { DriverConfig } from '../config/env'
|
||||
import Koa from 'koa'
|
||||
import BugSnagProvider, { BugSnagConfig } from './BugSnagProvider'
|
||||
import ErrorHandlerProvider, { ErrorHandlerProviderName } from './ErrorHandlerProvider'
|
||||
import SentryProvider, { SentryConfig } from './SentryProvider'
|
||||
|
||||
export type ErrorConfig = BugSnagConfig | SentryConfig
|
||||
|
||||
export interface ErrorHandlerTypeConfig extends DriverConfig {
|
||||
driver: ErrorHandlerProviderName
|
||||
}
|
||||
|
||||
export default class ErrorHandler {
|
||||
provider?: ErrorHandlerProvider
|
||||
constructor(config: ErrorConfig) {
|
||||
if (config?.driver === 'bugsnag') {
|
||||
this.provider = new BugSnagProvider(config)
|
||||
} else if (config?.driver === 'sentry') {
|
||||
this.provider = new SentryProvider(config)
|
||||
}
|
||||
}
|
||||
|
||||
attach(api: Koa) {
|
||||
this.provider?.attach(api)
|
||||
}
|
||||
}
|
7
apps/platform/src/error/ErrorHandlerProvider.ts
Normal file
7
apps/platform/src/error/ErrorHandlerProvider.ts
Normal file
|
@ -0,0 +1,7 @@
|
|||
import Koa from 'koa'
|
||||
|
||||
export type ErrorHandlerProviderName = 'bugsnag' | 'sentry'
|
||||
|
||||
export default interface ErrorHandlerProvider {
|
||||
attach(api: Koa): void
|
||||
}
|
24
apps/platform/src/error/SentryProvider.ts
Normal file
24
apps/platform/src/error/SentryProvider.ts
Normal file
|
@ -0,0 +1,24 @@
|
|||
import * as Sentry from '@sentry/node'
|
||||
import Koa from 'koa'
|
||||
import { ErrorHandlerTypeConfig } from './ErrorHandler'
|
||||
import ErrorHandlingProvider from './ErrorHandlerProvider'
|
||||
|
||||
export interface SentryConfig extends ErrorHandlerTypeConfig {
|
||||
driver: 'sentry'
|
||||
dsn: string
|
||||
}
|
||||
|
||||
export default class SentryProvider implements ErrorHandlingProvider {
|
||||
constructor(config: SentryConfig) {
|
||||
Sentry.init({ dsn: config.dsn })
|
||||
}
|
||||
|
||||
attach(api: Koa) {
|
||||
api.on('error', (err, ctx) => {
|
||||
Sentry.withScope(scope => {
|
||||
scope.setSDKProcessingMetadata({ request: ctx.request })
|
||||
Sentry.captureException(err)
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue