Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(repo): add stack traces to async REST errors #131

Merged
merged 6 commits into from
Apr 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
. "$(dirname -- "$0")/_/husky.sh"

npx lint-staged
npm run test
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

This is the official Camunda 8 JavaScript SDK. It is written in TypeScript and runs on Node.js. See why [this does not run in a web browser](https://github.com/camunda/camunda-8-js-sdk/issues/79).

Full API Docs are [here](https://camunda.github.io/camunda-8-js-sdk/). See the QUICKSTART.md file in [the repository](https://github.com/camunda/camunda-8-js-sdk) for a quick start.

## What does "supported" mean?

This is the official supported-by-Camunda Nodejs SDK for Camunda Platform 8.
Expand Down Expand Up @@ -34,7 +36,7 @@ In this release, the functionality of Camunda 8 is exposed via dedicated clients
import { Camunda8 } from '@camunda8/sdk'

const c8 = new Camunda8()
const zeebe = c8.getZeebeGrpcClient()
const zeebe = c8.getZeebeGrpcApiClient()
const operate = c8.getOperateApiClient()
const optimize = c8.getOptimizeApiClient()
const tasklist = c8.getTasklistApiClient()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { LosslessNumber } from 'lossless-json'

import { OperateApiClient } from '../../operate'
import { ProcessDefinition, Query } from '../../operate/lib/OperateDto'
import { ZeebeGrpcClient } from '../../zeebe'

jest.setTimeout(15000)
describe('Operate Integration', () => {
Expand Down Expand Up @@ -33,3 +34,20 @@ describe('Operate Integration', () => {
expect(defs.total).toBeGreaterThanOrEqual(0)
})
})

test('getJSONVariablesforProcess works', async () => {
const c = new OperateApiClient()
const zeebe = new ZeebeGrpcClient()
await zeebe.deployResource({
processFilename: 'src/__tests__/testdata/Operate-StraightThrough.bpmn',
})
const p = await zeebe.createProcessInstanceWithResult({
bpmnProcessId: 'operate-straightthrough',
variables: {
foo: 'bar',
},
})
await new Promise((res) => setTimeout(() => res(null), 5000))
const res = await c.getJSONVariablesforProcess(p.processInstanceKey)
expect(res.foo).toBe('bar')
})
32 changes: 32 additions & 0 deletions src/__tests__/testdata/Operate-StraightThrough.bpmn
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:modeler="http://camunda.org/schema/modeler/1.0" id="Definitions_1kv929v" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="5.21.0" modeler:executionPlatform="Camunda Cloud" modeler:executionPlatformVersion="8.4.0">
<bpmn:process id="operate-straightthrough" name="Operate Straight Through" isExecutable="true">
<bpmn:startEvent id="StartEvent_1" name="Start Operate Test">
<bpmn:outgoing>Flow_0wppa4s</bpmn:outgoing>
</bpmn:startEvent>
<bpmn:sequenceFlow id="Flow_0wppa4s" sourceRef="StartEvent_1" targetRef="Event_1h6ie86" />
<bpmn:endEvent id="Event_1h6ie86" name="End Operate Test">
<bpmn:incoming>Flow_0wppa4s</bpmn:incoming>
</bpmn:endEvent>
</bpmn:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="operate-straightthrough">
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
<dc:Bounds x="179" y="79" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="152" y="122" width="90" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_1h6ie86_di" bpmnElement="Event_1h6ie86">
<dc:Bounds x="432" y="79" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="407" y="122" width="86" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="Flow_0wppa4s_di" bpmnElement="Flow_0wppa4s">
<di:waypoint x="215" y="97" />
<di:waypoint x="432" y="97" />
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn:definitions>
24 changes: 13 additions & 11 deletions src/admin/lib/AdminApiClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,20 +44,22 @@ export class AdminApiClient {
https: {
certificateAuthority,
},
handlers: [
(options, next) => {
if (Object.isFrozen(options.context)) {
options.context = { ...options.context }
}
Error.captureStackTrace(options.context)
return next(options)
},
],
hooks: {
beforeError: [
(error) => {
const { request } = error
if (request) {
debug(`Error in request to ${request.options.url.href}`)
debug(
`Request headers: ${JSON.stringify(request.options.headers)}`
)
debug(`Error: ${error.code} - ${error.message}`)

// Attach more contextual information to the error object
error.message += ` (request to ${request.options.url.href})`
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
;(error as any).source = (error as any).options.context.stack.split(
'\n'
)
return error
},
],
Expand Down
23 changes: 13 additions & 10 deletions src/modeler/lib/ModelerAPIClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,19 +44,22 @@ export class ModelerApiClient {
certificateAuthority,
},
responseType: 'json',
handlers: [
(options, next) => {
if (Object.isFrozen(options.context)) {
options.context = { ...options.context }
}
Error.captureStackTrace(options.context)
return next(options)
},
],
hooks: {
beforeError: [
(error) => {
const { request } = error
if (request) {
debug(`Error in request to ${request.options.url.href}`)
debug(
`Request headers: ${JSON.stringify(request.options.headers)}`
)
debug(`Error: ${error.code} - ${error.message}`)
// Attach more contextual information to the error object
error.message += ` (request to ${request.options.url.href})`
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
;(error as any).source = (error as any).options.context.stack.split(
'\n'
)
return error
},
],
Expand Down
28 changes: 14 additions & 14 deletions src/operate/lib/OperateApiClient.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { debug as d } from 'debug'
import got from 'got'

import {
Expand Down Expand Up @@ -32,8 +31,6 @@ import { parseSearchResults } from './parseSearchResults'

const OPERATE_API_VERSION = 'v1'

const debug = d('camunda:operate')

type JSONDoc = { [key: string]: string | boolean | number | JSONDoc }
type EnhanceWithTenantIdIfMissing<T> = T extends {
filter: { tenantId: string | undefined }
Expand Down Expand Up @@ -95,20 +92,23 @@ export class OperateApiClient {
https: {
certificateAuthority,
},
handlers: [
(options, next) => {
if (Object.isFrozen(options.context)) {
options.context = { ...options.context }
}
Error.captureStackTrace(options.context)

return next(options)
},
],
hooks: {
beforeError: [
(error) => {
const { request } = error
if (request) {
debug(`Error in request to ${request.options.url.href}`)
debug(
`Request headers: ${JSON.stringify(request.options.headers)}`
)
debug(`Error: ${error.code} - ${error.message}`)

// Attach more contextual information to the error object
error.message += ` (request to ${request.options.url.href})`
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
;(error as any).source = (error as any).options.context.stack.split(
'\n'
)
return error
},
],
Expand Down
27 changes: 13 additions & 14 deletions src/optimize/lib/OptimizeApiClient.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { debug as d } from 'debug'
import got from 'got'

import {
Expand All @@ -24,8 +23,6 @@ import {
} from './APIObjects'
import { ReportResults } from './ReportResults'

const debug = d('camunda:optimize')

/**
* @description The high-level API client for Optimize.
* @example
Expand Down Expand Up @@ -76,20 +73,22 @@ export class OptimizeApiClient {
https: {
certificateAuthority,
},
handlers: [
(options, next) => {
if (Object.isFrozen(options.context)) {
options.context = { ...options.context }
}
Error.captureStackTrace(options.context)
return next(options)
},
],
hooks: {
beforeError: [
(error) => {
const { request } = error
if (request) {
debug(`Error in request to ${request.options.url.href}`)
debug(
`Request headers: ${JSON.stringify(request.options.headers)}`
)
debug(`Error: ${error.code} - ${error.message}`)

// Attach more contextual information to the error object
error.message += ` (request to ${request.options.url.href})`
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
;(error as any).source = (error as any).options.context.stack.split(
'\n'
)
return error
},
],
Expand Down
24 changes: 13 additions & 11 deletions src/tasklist/lib/TasklistApiClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,20 +77,22 @@ export class TasklistApiClient {
https: {
certificateAuthority,
},
handlers: [
(options, next) => {
if (Object.isFrozen(options.context)) {
options.context = { ...options.context }
}
Error.captureStackTrace(options.context)
return next(options)
},
],
hooks: {
beforeError: [
(error) => {
const { request } = error
if (request) {
debug(`Error in request to ${request.options.url.href}`)
debug(
`Request headers: ${JSON.stringify(request.options.headers)}`
)
debug(`Error: ${error.code} - ${error.message}`)

// Attach more contextual information to the error object
error.message += ` (request to ${request.options.url.href})`
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
;(error as any).source = (error as any).options.context.stack.split(
'\n'
)
return error
},
],
Expand Down