@atlaskit/link-datasource 1.18.0 → 1.18.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # @atlaskit/link-datasource
2
2
 
3
+ ## 1.18.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [#43497](https://bitbucket.org/atlassian/atlassian-frontend/pull-requests/43497) [`049969f8eb1`](https://bitbucket.org/atlassian/atlassian-frontend/commits/049969f8eb1) - Added error logging to the datasource try catches.
8
+ - Updated dependencies
9
+
3
10
  ## 1.18.0
4
11
 
5
12
  ### Minor Changes
@@ -7,5 +7,5 @@ exports.packageMetaData = exports.EVENT_CHANNEL = void 0;
7
7
  var EVENT_CHANNEL = exports.EVENT_CHANNEL = 'media';
8
8
  var packageMetaData = exports.packageMetaData = {
9
9
  packageName: "@atlaskit/link-datasource",
10
- packageVersion: "1.18.0"
10
+ packageVersion: "1.18.1"
11
11
  };
@@ -13,6 +13,7 @@ var _react = require("react");
13
13
  var _isEqual = _interopRequireDefault(require("lodash/isEqual"));
14
14
  var _linkClientExtension = require("@atlaskit/link-client-extension");
15
15
  var _analytics = require("../analytics");
16
+ var _useErrorLogger2 = _interopRequireDefault(require("./useErrorLogger"));
16
17
  var useDatasourceTableState = exports.useDatasourceTableState = function useDatasourceTableState(_ref) {
17
18
  var datasourceId = _ref.datasourceId,
18
19
  parameters = _ref.parameters,
@@ -20,6 +21,8 @@ var useDatasourceTableState = exports.useDatasourceTableState = function useData
20
21
  fieldKeys = _ref$fieldKeys === void 0 ? [] : _ref$fieldKeys;
21
22
  var _useDatasourceAnalyti = (0, _analytics.useDatasourceAnalyticsEvents)(),
22
23
  fireEvent = _useDatasourceAnalyti.fireEvent;
24
+ var _useErrorLogger = (0, _useErrorLogger2.default)(),
25
+ captureError = _useErrorLogger.captureError;
23
26
  var idFieldCount = 1;
24
27
  var keyFieldCount = 1;
25
28
  var _useState = (0, _react.useState)([]),
@@ -110,25 +113,26 @@ var useDatasourceTableState = exports.useDatasourceTableState = function useData
110
113
  allColumns = schema.properties;
111
114
  newColumns = allColumns.filter(isColumnNotPresentInCurrentColumnsList);
112
115
  newColumns.length > 0 && setColumns([].concat((0, _toConsumableArray2.default)(columns), (0, _toConsumableArray2.default)(newColumns)));
113
- _context.next = 23;
116
+ _context.next = 24;
114
117
  break;
115
118
  case 17:
116
119
  _context.prev = 17;
117
120
  _context.t0 = _context["catch"](2);
121
+ captureError('loadDatasourceDetails', _context.t0);
118
122
  if (!(_context.t0 instanceof Response && (_context.t0.status === 401 || _context.t0.status === 403))) {
119
- _context.next = 22;
123
+ _context.next = 23;
120
124
  break;
121
125
  }
122
126
  setStatus('unauthorized');
123
127
  return _context.abrupt("return");
124
- case 22:
125
- setStatus('rejected');
126
128
  case 23:
129
+ setStatus('rejected');
130
+ case 24:
127
131
  case "end":
128
132
  return _context.stop();
129
133
  }
130
134
  }, _callee, null, [[2, 17]]);
131
- })), [columns, datasourceId, getDatasourceDetails, parameters]);
135
+ })), [captureError, columns, datasourceId, getDatasourceDetails, parameters]);
132
136
  var applySchemaProperties = (0, _react.useCallback)(function (schema, fieldKeys) {
133
137
  var properties = schema.properties,
134
138
  _schema$defaultProper = schema.defaultProperties,
@@ -256,25 +260,26 @@ var useDatasourceTableState = exports.useDatasourceTableState = function useData
256
260
  });
257
261
  }
258
262
  setStatus('resolved');
259
- _context2.next = 42;
263
+ _context2.next = 43;
260
264
  break;
261
265
  case 36:
262
266
  _context2.prev = 36;
263
267
  _context2.t0 = _context2["catch"](7);
268
+ captureError('onNextPage', _context2.t0);
264
269
  if (!(_context2.t0 instanceof Response && (_context2.t0.status === 401 || _context2.t0.status === 403))) {
265
- _context2.next = 41;
270
+ _context2.next = 42;
266
271
  break;
267
272
  }
268
273
  setStatus('unauthorized');
269
274
  return _context2.abrupt("return");
270
- case 41:
271
- setStatus('rejected');
272
275
  case 42:
276
+ setStatus('rejected');
277
+ case 43:
273
278
  case "end":
274
279
  return _context2.stop();
275
280
  }
276
281
  }, _callee2, null, [[7, 36]]);
277
- })), [parameters, fieldKeys, nextCursor, getDatasourceData, datasourceId, responseItems === null || responseItems === void 0 ? void 0 : responseItems.length, applySchemaProperties, fireEvent, fullSchema]);
282
+ })), [captureError, parameters, fieldKeys, nextCursor, getDatasourceData, datasourceId, responseItems === null || responseItems === void 0 ? void 0 : responseItems.length, applySchemaProperties, fireEvent, fullSchema]);
278
283
  var reset = (0, _react.useCallback)(function (options) {
279
284
  setStatus('empty');
280
285
  setResponseItems([]);
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _react = require("react");
8
+ var _sentry = require("@atlaskit/linking-common/sentry");
9
+ var _utils = require("@atlaskit/linking-common/utils");
10
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
11
+ var _analytics = require("../analytics");
12
+ var getNetworkFields = function getNetworkFields(error) {
13
+ return error instanceof Response ? {
14
+ traceId: (0, _utils.getTraceId)(error),
15
+ status: error.status
16
+ } : {
17
+ traceId: null,
18
+ status: null
19
+ };
20
+ };
21
+ var useErrorLogger = function useErrorLogger() {
22
+ var _useDatasourceAnalyti = (0, _analytics.useDatasourceAnalyticsEvents)(),
23
+ fireEvent = _useDatasourceAnalyti.fireEvent;
24
+
25
+ /**
26
+ * Sentry is good because it can retrieve name, message, stacktrace of an Error. That's why we will send to Sentry only
27
+ * if an error is instance of `Error`. Sentry is also capable of some PII scrubbing of these risky fields.
28
+ *
29
+ * We will send to Splunk every single time, though, but we won't send PII risky fields.
30
+ */
31
+ var captureError = (0, _react.useCallback)(function (errorLocation, error) {
32
+ var _getNetworkFields = getNetworkFields(error),
33
+ traceId = _getNetworkFields.traceId,
34
+ status = _getNetworkFields.status;
35
+ fireEvent('operational.datasource.operationFailed', {
36
+ errorLocation: errorLocation,
37
+ traceId: traceId,
38
+ status: status
39
+ });
40
+ if ((0, _platformFeatureFlags.getBooleanFF)('platform.linking-platform.datasources.enable-sentry-client') && error instanceof Error) {
41
+ (0, _sentry.captureException)(error, 'link-datasource');
42
+ }
43
+ }, [fireEvent]);
44
+ return {
45
+ captureError: captureError
46
+ };
47
+ };
48
+ var _default = exports.default = useErrorLogger;
@@ -1,5 +1,5 @@
1
1
  export const EVENT_CHANNEL = 'media';
2
2
  export const packageMetaData = {
3
3
  packageName: "@atlaskit/link-datasource",
4
- packageVersion: "1.18.0"
4
+ packageVersion: "1.18.1"
5
5
  };
@@ -2,6 +2,7 @@ import { useCallback, useEffect, useState } from 'react';
2
2
  import isEqual from 'lodash/isEqual';
3
3
  import { DEFAULT_GET_DATASOURCE_DATA_PAGE_SIZE, useDatasourceClientExtension } from '@atlaskit/link-client-extension';
4
4
  import { useDatasourceAnalyticsEvents } from '../analytics';
5
+ import useErrorLogger from './useErrorLogger';
5
6
  export const useDatasourceTableState = ({
6
7
  datasourceId,
7
8
  parameters,
@@ -10,6 +11,9 @@ export const useDatasourceTableState = ({
10
11
  const {
11
12
  fireEvent
12
13
  } = useDatasourceAnalyticsEvents();
14
+ const {
15
+ captureError
16
+ } = useErrorLogger();
13
17
  const idFieldCount = 1;
14
18
  const keyFieldCount = 1;
15
19
  const [defaultVisibleColumnKeys, setDefaultVisibleColumnKeys] = useState([]);
@@ -54,13 +58,14 @@ export const useDatasourceTableState = ({
54
58
  const newColumns = allColumns.filter(isColumnNotPresentInCurrentColumnsList);
55
59
  newColumns.length > 0 && setColumns([...columns, ...newColumns]);
56
60
  } catch (e) {
61
+ captureError('loadDatasourceDetails', e);
57
62
  if (e instanceof Response && (e.status === 401 || e.status === 403)) {
58
63
  setStatus('unauthorized');
59
64
  return;
60
65
  }
61
66
  setStatus('rejected');
62
67
  }
63
- }, [columns, datasourceId, getDatasourceDetails, parameters]);
68
+ }, [captureError, columns, datasourceId, getDatasourceDetails, parameters]);
64
69
  const applySchemaProperties = useCallback((schema, fieldKeys) => {
65
70
  let {
66
71
  properties,
@@ -160,13 +165,14 @@ export const useDatasourceTableState = ({
160
165
  }
161
166
  setStatus('resolved');
162
167
  } catch (e) {
168
+ captureError('onNextPage', e);
163
169
  if (e instanceof Response && (e.status === 401 || e.status === 403)) {
164
170
  setStatus('unauthorized');
165
171
  return;
166
172
  }
167
173
  setStatus('rejected');
168
174
  }
169
- }, [parameters, fieldKeys, nextCursor, getDatasourceData, datasourceId, responseItems === null || responseItems === void 0 ? void 0 : responseItems.length, applySchemaProperties, fireEvent, fullSchema]);
175
+ }, [captureError, parameters, fieldKeys, nextCursor, getDatasourceData, datasourceId, responseItems === null || responseItems === void 0 ? void 0 : responseItems.length, applySchemaProperties, fireEvent, fullSchema]);
170
176
  const reset = useCallback(options => {
171
177
  setStatus('empty');
172
178
  setResponseItems([]);
@@ -0,0 +1,44 @@
1
+ import { useCallback } from 'react';
2
+ import { captureException } from '@atlaskit/linking-common/sentry';
3
+ import { getTraceId } from '@atlaskit/linking-common/utils';
4
+ import { getBooleanFF } from '@atlaskit/platform-feature-flags';
5
+ import { useDatasourceAnalyticsEvents } from '../analytics';
6
+ const getNetworkFields = error => {
7
+ return error instanceof Response ? {
8
+ traceId: getTraceId(error),
9
+ status: error.status
10
+ } : {
11
+ traceId: null,
12
+ status: null
13
+ };
14
+ };
15
+ const useErrorLogger = () => {
16
+ const {
17
+ fireEvent
18
+ } = useDatasourceAnalyticsEvents();
19
+
20
+ /**
21
+ * Sentry is good because it can retrieve name, message, stacktrace of an Error. That's why we will send to Sentry only
22
+ * if an error is instance of `Error`. Sentry is also capable of some PII scrubbing of these risky fields.
23
+ *
24
+ * We will send to Splunk every single time, though, but we won't send PII risky fields.
25
+ */
26
+ const captureError = useCallback((errorLocation, error) => {
27
+ const {
28
+ traceId,
29
+ status
30
+ } = getNetworkFields(error);
31
+ fireEvent('operational.datasource.operationFailed', {
32
+ errorLocation,
33
+ traceId,
34
+ status
35
+ });
36
+ if (getBooleanFF('platform.linking-platform.datasources.enable-sentry-client') && error instanceof Error) {
37
+ captureException(error, 'link-datasource');
38
+ }
39
+ }, [fireEvent]);
40
+ return {
41
+ captureError
42
+ };
43
+ };
44
+ export default useErrorLogger;
@@ -1,5 +1,5 @@
1
1
  export var EVENT_CHANNEL = 'media';
2
2
  export var packageMetaData = {
3
3
  packageName: "@atlaskit/link-datasource",
4
- packageVersion: "1.18.0"
4
+ packageVersion: "1.18.1"
5
5
  };
@@ -6,6 +6,7 @@ import { useCallback, useEffect, useState } from 'react';
6
6
  import isEqual from 'lodash/isEqual';
7
7
  import { DEFAULT_GET_DATASOURCE_DATA_PAGE_SIZE, useDatasourceClientExtension } from '@atlaskit/link-client-extension';
8
8
  import { useDatasourceAnalyticsEvents } from '../analytics';
9
+ import useErrorLogger from './useErrorLogger';
9
10
  export var useDatasourceTableState = function useDatasourceTableState(_ref) {
10
11
  var datasourceId = _ref.datasourceId,
11
12
  parameters = _ref.parameters,
@@ -13,6 +14,8 @@ export var useDatasourceTableState = function useDatasourceTableState(_ref) {
13
14
  fieldKeys = _ref$fieldKeys === void 0 ? [] : _ref$fieldKeys;
14
15
  var _useDatasourceAnalyti = useDatasourceAnalyticsEvents(),
15
16
  fireEvent = _useDatasourceAnalyti.fireEvent;
17
+ var _useErrorLogger = useErrorLogger(),
18
+ captureError = _useErrorLogger.captureError;
16
19
  var idFieldCount = 1;
17
20
  var keyFieldCount = 1;
18
21
  var _useState = useState([]),
@@ -103,25 +106,26 @@ export var useDatasourceTableState = function useDatasourceTableState(_ref) {
103
106
  allColumns = schema.properties;
104
107
  newColumns = allColumns.filter(isColumnNotPresentInCurrentColumnsList);
105
108
  newColumns.length > 0 && setColumns([].concat(_toConsumableArray(columns), _toConsumableArray(newColumns)));
106
- _context.next = 23;
109
+ _context.next = 24;
107
110
  break;
108
111
  case 17:
109
112
  _context.prev = 17;
110
113
  _context.t0 = _context["catch"](2);
114
+ captureError('loadDatasourceDetails', _context.t0);
111
115
  if (!(_context.t0 instanceof Response && (_context.t0.status === 401 || _context.t0.status === 403))) {
112
- _context.next = 22;
116
+ _context.next = 23;
113
117
  break;
114
118
  }
115
119
  setStatus('unauthorized');
116
120
  return _context.abrupt("return");
117
- case 22:
118
- setStatus('rejected');
119
121
  case 23:
122
+ setStatus('rejected');
123
+ case 24:
120
124
  case "end":
121
125
  return _context.stop();
122
126
  }
123
127
  }, _callee, null, [[2, 17]]);
124
- })), [columns, datasourceId, getDatasourceDetails, parameters]);
128
+ })), [captureError, columns, datasourceId, getDatasourceDetails, parameters]);
125
129
  var applySchemaProperties = useCallback(function (schema, fieldKeys) {
126
130
  var properties = schema.properties,
127
131
  _schema$defaultProper = schema.defaultProperties,
@@ -249,25 +253,26 @@ export var useDatasourceTableState = function useDatasourceTableState(_ref) {
249
253
  });
250
254
  }
251
255
  setStatus('resolved');
252
- _context2.next = 42;
256
+ _context2.next = 43;
253
257
  break;
254
258
  case 36:
255
259
  _context2.prev = 36;
256
260
  _context2.t0 = _context2["catch"](7);
261
+ captureError('onNextPage', _context2.t0);
257
262
  if (!(_context2.t0 instanceof Response && (_context2.t0.status === 401 || _context2.t0.status === 403))) {
258
- _context2.next = 41;
263
+ _context2.next = 42;
259
264
  break;
260
265
  }
261
266
  setStatus('unauthorized');
262
267
  return _context2.abrupt("return");
263
- case 41:
264
- setStatus('rejected');
265
268
  case 42:
269
+ setStatus('rejected');
270
+ case 43:
266
271
  case "end":
267
272
  return _context2.stop();
268
273
  }
269
274
  }, _callee2, null, [[7, 36]]);
270
- })), [parameters, fieldKeys, nextCursor, getDatasourceData, datasourceId, responseItems === null || responseItems === void 0 ? void 0 : responseItems.length, applySchemaProperties, fireEvent, fullSchema]);
275
+ })), [captureError, parameters, fieldKeys, nextCursor, getDatasourceData, datasourceId, responseItems === null || responseItems === void 0 ? void 0 : responseItems.length, applySchemaProperties, fireEvent, fullSchema]);
271
276
  var reset = useCallback(function (options) {
272
277
  setStatus('empty');
273
278
  setResponseItems([]);
@@ -0,0 +1,42 @@
1
+ import { useCallback } from 'react';
2
+ import { captureException } from '@atlaskit/linking-common/sentry';
3
+ import { getTraceId } from '@atlaskit/linking-common/utils';
4
+ import { getBooleanFF } from '@atlaskit/platform-feature-flags';
5
+ import { useDatasourceAnalyticsEvents } from '../analytics';
6
+ var getNetworkFields = function getNetworkFields(error) {
7
+ return error instanceof Response ? {
8
+ traceId: getTraceId(error),
9
+ status: error.status
10
+ } : {
11
+ traceId: null,
12
+ status: null
13
+ };
14
+ };
15
+ var useErrorLogger = function useErrorLogger() {
16
+ var _useDatasourceAnalyti = useDatasourceAnalyticsEvents(),
17
+ fireEvent = _useDatasourceAnalyti.fireEvent;
18
+
19
+ /**
20
+ * Sentry is good because it can retrieve name, message, stacktrace of an Error. That's why we will send to Sentry only
21
+ * if an error is instance of `Error`. Sentry is also capable of some PII scrubbing of these risky fields.
22
+ *
23
+ * We will send to Splunk every single time, though, but we won't send PII risky fields.
24
+ */
25
+ var captureError = useCallback(function (errorLocation, error) {
26
+ var _getNetworkFields = getNetworkFields(error),
27
+ traceId = _getNetworkFields.traceId,
28
+ status = _getNetworkFields.status;
29
+ fireEvent('operational.datasource.operationFailed', {
30
+ errorLocation: errorLocation,
31
+ traceId: traceId,
32
+ status: status
33
+ });
34
+ if (getBooleanFF('platform.linking-platform.datasources.enable-sentry-client') && error instanceof Error) {
35
+ captureException(error, 'link-datasource');
36
+ }
37
+ }, [fireEvent]);
38
+ return {
39
+ captureError: captureError
40
+ };
41
+ };
42
+ export default useErrorLogger;
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Generates Typescript types for analytics events from analytics.spec.yaml
5
5
  *
6
- * @codegen <<SignedSource::ccda345ed2d15f3bbe167f871f676090>>
6
+ * @codegen <<SignedSource::4e6414d2c19c29a67f20beee73d4b788>>
7
7
  * @codegenCommand yarn workspace @atlassian/analytics-tooling run analytics:codegen link-datasource
8
8
  */
9
9
  export type PackageMetaDataType = {
@@ -59,6 +59,11 @@ export type DatasourceRenderSuccessAttributesType = {
59
59
  display: 'table';
60
60
  };
61
61
  export type DatasourceRenderFailureAttributesType = {};
62
+ export type DatasourceOperationFailedAttributesType = {
63
+ errorLocation: string | null;
64
+ traceId: string | null;
65
+ status: number | null;
66
+ };
62
67
  export type NextItemLoadedAttributesType = {
63
68
  destinationObjectTypes: unknown[];
64
69
  extensionKey: string | null;
@@ -155,6 +160,9 @@ export type AnalyticsEventAttributes = {
155
160
  /**
156
161
  * Fired when an inserted datasource fails to render */
157
162
  'operational.datasource.renderFailure': DatasourceRenderFailureAttributesType;
163
+ /**
164
+ * Fired when a generic operation failed */
165
+ 'operational.datasource.operationFailed': DatasourceOperationFailedAttributesType;
158
166
  /**
159
167
  * Fired when user scrolls to the next page/list of the objects */
160
168
  'track.nextItem.loaded': NextItemLoadedAttributesType;
@@ -0,0 +1,4 @@
1
+ declare const useErrorLogger: () => {
2
+ captureError: (errorLocation: string, error: unknown) => void;
3
+ };
4
+ export default useErrorLogger;
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Generates Typescript types for analytics events from analytics.spec.yaml
5
5
  *
6
- * @codegen <<SignedSource::ccda345ed2d15f3bbe167f871f676090>>
6
+ * @codegen <<SignedSource::4e6414d2c19c29a67f20beee73d4b788>>
7
7
  * @codegenCommand yarn workspace @atlassian/analytics-tooling run analytics:codegen link-datasource
8
8
  */
9
9
  export type PackageMetaDataType = {
@@ -59,6 +59,11 @@ export type DatasourceRenderSuccessAttributesType = {
59
59
  display: 'table';
60
60
  };
61
61
  export type DatasourceRenderFailureAttributesType = {};
62
+ export type DatasourceOperationFailedAttributesType = {
63
+ errorLocation: string | null;
64
+ traceId: string | null;
65
+ status: number | null;
66
+ };
62
67
  export type NextItemLoadedAttributesType = {
63
68
  destinationObjectTypes: unknown[];
64
69
  extensionKey: string | null;
@@ -155,6 +160,9 @@ export type AnalyticsEventAttributes = {
155
160
  /**
156
161
  * Fired when an inserted datasource fails to render */
157
162
  'operational.datasource.renderFailure': DatasourceRenderFailureAttributesType;
163
+ /**
164
+ * Fired when a generic operation failed */
165
+ 'operational.datasource.operationFailed': DatasourceOperationFailedAttributesType;
158
166
  /**
159
167
  * Fired when user scrolls to the next page/list of the objects */
160
168
  'track.nextItem.loaded': NextItemLoadedAttributesType;
@@ -0,0 +1,4 @@
1
+ declare const useErrorLogger: () => {
2
+ captureError: (errorLocation: string, error: unknown) => void;
3
+ };
4
+ export default useErrorLogger;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/link-datasource",
3
- "version": "1.18.0",
3
+ "version": "1.18.1",
4
4
  "description": "UI Components to support linking platform dataset feature",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"
@@ -46,7 +46,7 @@
46
46
  "@atlaskit/jql-ast": "^3.0.0",
47
47
  "@atlaskit/jql-editor-autocomplete-rest": "^2.0.0",
48
48
  "@atlaskit/link-client-extension": "^1.8.0",
49
- "@atlaskit/linking-common": "^4.18.0",
49
+ "@atlaskit/linking-common": "^4.19.0",
50
50
  "@atlaskit/linking-types": "^8.5.0",
51
51
  "@atlaskit/lozenge": "^11.4.0",
52
52
  "@atlaskit/modal-dialog": "^12.8.0",
@@ -138,6 +138,9 @@
138
138
  "platform-feature-flags": {
139
139
  "platform.linking-platform.datasource.show-jlol-basic-filters": {
140
140
  "type": "boolean"
141
+ },
142
+ "platform.linking-platform.datasources.enable-sentry-client": {
143
+ "type": "boolean"
141
144
  }
142
145
  }
143
146
  }