Skip to content

Commit 34d8126

Browse files
authored
Stop throwing unnecessary errors with adding annotations, metadata, errors (#467)
* Stop throwing unnecessary errors with adding annotations, metadata, and errors. * Validate segments do not throw errors in tests. * Avoid adding invalid keys to segment metadata and annotations.
1 parent 0f6bee9 commit 34d8126

File tree

4 files changed

+59
-38
lines changed

4 files changed

+59
-38
lines changed

packages/core/lib/segments/attributes/subsegment.js

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -122,12 +122,16 @@ Subsegment.prototype.addPrecursorId = function(id) {
122122
*/
123123

124124
Subsegment.prototype.addAnnotation = function(key, value) {
125-
if (!(typeof value === 'boolean' || typeof value === 'string' || (typeof value === 'number' && isFinite(value)))) {
126-
throw new Error('Failed to add annotation key: ' + key + ' value: ' + value + ' to subsegment ' +
125+
if (typeof value !== 'boolean' && typeof value !== 'string' && !isFinite(value)) {
126+
logger.getLogger().error('Failed to add annotation key: ' + key + ' value: ' + value + ' to subsegment ' +
127127
this.name + '. Value must be of type string, number or boolean.');
128-
} else if (typeof key !== 'string') {
129-
throw new Error('Failed to add annotation key: ' + key + ' value: ' + value + ' to subsegment ' +
128+
return;
129+
}
130+
131+
if (typeof key !== 'string') {
132+
logger.getLogger().error('Failed to add annotation key: ' + key + ' value: ' + value + ' to subsegment ' +
130133
this.name + '. Key must be of type string.');
134+
return;
131135
}
132136

133137
if (this.annotations === undefined) {
@@ -147,11 +151,15 @@ Subsegment.prototype.addAnnotation = function(key, value) {
147151

148152
Subsegment.prototype.addMetadata = function(key, value, namespace) {
149153
if (typeof key !== 'string') {
150-
throw new Error('Failed to add annotation key: ' + key + ' value: ' + value + ' to subsegment ' +
154+
logger.getLogger().error('Failed to add metadata key: ' + key + ' value: ' + value + ' to subsegment ' +
151155
this.name + '. Key must be of type string.');
152-
} else if (namespace && typeof namespace !== 'string') {
153-
throw new Error('Failed to add annotation key: ' + key + ' value: ' + value + 'namespace: ' + namespace + ' to subsegment ' +
156+
return;
157+
}
158+
159+
if (namespace && typeof namespace !== 'string') {
160+
logger.getLogger().error('Failed to add metadata key: ' + key + ' value: ' + value + ' to subsegment ' +
154161
this.name + '. Namespace must be of type string.');
162+
return;
155163
}
156164

157165
var ns = namespace || 'default';
@@ -164,7 +172,7 @@ Subsegment.prototype.addMetadata = function(key, value, namespace) {
164172
this.metadata[ns] = {};
165173
}
166174

167-
this.metadata[ns][key] = value;
175+
this.metadata[ns][key] = value !== null && value !== undefined ? value : '';
168176
};
169177

170178
Subsegment.prototype.addSqlData = function addSqlData(sqlData) {
@@ -182,8 +190,9 @@ Subsegment.prototype.addSqlData = function addSqlData(sqlData) {
182190

183191
Subsegment.prototype.addError = function addError(err, remote) {
184192
if (err == null || typeof err !== 'object' && typeof(err) !== 'string') {
185-
throw new Error('Failed to add error:' + err + ' to subsegment "' + this.name +
186-
'". Not an object or string literal.');
193+
logger.getLogger().error('Failed to add error:' + err + ' to subsegment "' + this.name +
194+
'". Not an object or string literal.');
195+
return;
187196
}
188197

189198
this.addFaultFlag();
@@ -323,8 +332,9 @@ Subsegment.prototype.isClosed = function isClosed() {
323332

324333
Subsegment.prototype.flush = function flush() {
325334
if (!this.parent || !this.segment) {
326-
throw new Error('Failed to flush subsegment: ' + this.name + '. Subsegment must be added ' +
335+
logger.getLogger().error('Failed to flush subsegment: ' + this.name + '. Subsegment must be added ' +
327336
'to a segment chain to flush.');
337+
return;
328338
}
329339

330340
if (this.segment.trace_id) {

packages/core/lib/segments/segment.js

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,14 @@ Segment.prototype.addIncomingRequestData = function addIncomingRequestData(data)
8282

8383
Segment.prototype.addAnnotation = function addAnnotation(key, value) {
8484
if (typeof value !== 'boolean' && typeof value !== 'string' && !isFinite(value)) {
85-
logger.getLogger().error('Add annotation key: ' + key + ' value: ' + value + ' failed.' +
86-
' Annotations must be of type string, number or boolean.');
85+
logger.getLogger().error('Failed to add annotation key: ' + key + ' value: ' + value + ' to subsegment ' +
86+
this.name + '. Value must be of type string, number or boolean.');
87+
return;
88+
}
89+
90+
if (typeof key !== 'string') {
91+
logger.getLogger().error('Failed to add annotation key: ' + key + ' value: ' + value + ' to subsegment ' +
92+
this.name + '. Key must be of type string.');
8793
return;
8894
}
8995

@@ -116,11 +122,15 @@ Segment.prototype.setUser = function (user) {
116122

117123
Segment.prototype.addMetadata = function(key, value, namespace) {
118124
if (typeof key !== 'string') {
119-
throw new Error('Failed to add annotation key: ' + key + ' value: ' + value + ' to subsegment ' +
125+
logger.getLogger().error('Failed to add metadata key: ' + key + ' value: ' + value + ' to segment ' +
120126
this.name + '. Key must be of type string.');
121-
} else if (namespace && typeof namespace !== 'string') {
122-
throw new Error('Failed to add annotation key: ' + key + ' value: ' + value + 'namespace: ' + namespace + ' to subsegment ' +
127+
return;
128+
}
129+
130+
if (namespace && typeof namespace !== 'string') {
131+
logger.getLogger().error('Failed to add metadata key: ' + key + ' value: ' + value + ' to segment ' +
123132
this.name + '. Namespace must be of type string.');
133+
return;
124134
}
125135

126136
var ns = namespace || 'default';
@@ -133,7 +143,7 @@ Segment.prototype.addMetadata = function(key, value, namespace) {
133143
this.metadata[ns] = {};
134144
}
135145

136-
this.metadata[ns][key] = value;
146+
this.metadata[ns][key] = value !== null && value !== undefined ? value : '';
137147
};
138148

139149
/**
@@ -255,8 +265,9 @@ Segment.prototype.removeSubsegment = function removeSubsegment(subsegment) {
255265

256266
Segment.prototype.addError = function addError(err, remote) {
257267
if (err == null || typeof err !== 'object' && typeof(err) !== 'string') {
258-
throw new Error('Failed to add error:' + err + ' to subsegment "' + this.name +
259-
'". Not an object or string literal.');
268+
logger.getLogger().error('Failed to add error:' + err + ' to subsegment "' + this.name +
269+
'". Not an object or string literal.');
270+
return;
260271
}
261272

262273
this.addFaultFlag();

packages/core/test/unit/segments/attributes/subsegment.test.js

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ var sinonChai = require('sinon-chai');
66
var CapturedException = require('../../../../lib/segments/attributes/captured_exception');
77
var SegmentUtils = require('../../../../lib/segments/segment_utils');
88
var Subsegment = require('../../../../lib/segments/attributes/subsegment');
9+
var logger = require('../../../../lib/logger');
910

1011
chai.should();
1112
chai.use(sinonChai);
@@ -117,10 +118,12 @@ describe('Subsegment', function() {
117118
assert.equal(subsegment.cause.exceptions.length, 2);
118119
});
119120

120-
it('should throw an error on other types', function() {
121-
assert.throws(function() {
122-
subsegment.addError(3);
123-
});
121+
it('should accept invalid types and log an error', function() {
122+
const loggerMock = sandbox.mock(logger.getLogger());
123+
loggerMock.expects('error').once();
124+
subsegment.addError(3);
125+
loggerMock.verify();
126+
assert.notEqual(subsegment.fault, true);
124127
});
125128

126129
it('should set fault to true by default', function() {
@@ -261,18 +264,12 @@ describe('Subsegment', function() {
261264
emitStub.reset();
262265
});
263266

264-
it('should throw an error if the subsegment has no parent', function() {
267+
it('should not throw an error when subsegment flushes', function() {
265268
delete child.parent;
266-
assert.throws( function() {
267-
child.flush();
268-
}, Error);
269-
});
270-
271-
it('should throw an error if the subsegment has no segment', function() {
272-
delete child.segment;
273-
assert.throws( function() {
274-
child.flush();
275-
}, Error);
269+
const loggerMock = sandbox.mock(logger.getLogger());
270+
loggerMock.expects('error').once();
271+
child.flush();
272+
loggerMock.verify();
276273
});
277274

278275
it('should set the parent_id, trace_id and type properties', function() {

packages/core/test/unit/segments/segment.test.js

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ var SegmentEmitter = require('../../../lib/segment_emitter');
88
var SegmentUtils = require('../../../lib/segments/segment_utils');
99
var Segment = require('../../../lib/segments/segment');
1010
var Subsegment = require('../../../lib/segments/attributes/subsegment');
11+
var logger = require('../../../lib/logger');
1112

1213
chai.should();
1314
chai.use(sinonChai);
@@ -280,10 +281,12 @@ describe('Segment', function() {
280281
assert.equal(segment.cause.exceptions.length, 2);
281282
});
282283

283-
it('should throw an error on other types', function() {
284-
assert.throws(function() {
285-
segment.addError(3);
286-
});
284+
it('should accept invalid types and log an error', function() {
285+
const loggerMock = sandbox.mock(logger.getLogger());
286+
loggerMock.expects('error').once();
287+
segment.addError(3);
288+
loggerMock.verify();
289+
assert.notEqual(segment.fault, true);
287290
});
288291

289292
it('should set fault to true by default', function() {

0 commit comments

Comments
 (0)