Inside a callback I build an object I build to send out in my Express app:
this.response = {
owner: data.actions[1].causes[0].shortDescription,
build_version: data.actions[0].parameters[0].value,
branch_to_merge: data.actions[0].parameters[1].value,
jira_tickets: data.actions[0].parameters[2].value,
build_description: data.actions[0].parameters[3].value,
outcome: data.result
};
If I get a different response than what I'm used to I get a fatal cannot find 'property' of undefined
error that crashes my server caused by these: data.actions[1].causes[0].shortDescription
.
I was wondering what to do about it and I thought I could just put it in a try catch
but that seems wrong.
What's considered a good way of dealing with this?
The object literal is a short form of creating an object. Define an object in the { } brackets with key:value pairs separated by a comma. The key would be the name of the property and the value will be a literal value or a function.
A try catch block is placed around code that could throw an exception. If an exception is thrown, this try catch block will handle the exception to ensure that the application does not cause an unhandled exception, user error, or crash the application.
An object literal is a list of zero or more pairs of property names and associated values of an object, enclosed in curly braces ( {} ).
The try statement allows you to define a block of code to be tested for errors while it is being executed. The catch statement allows you to define a block of code to be executed, if an error occurs in the try block.
In your statement you have:
That's what try/catch handles best. Dealing with the same type of error from a block of code and handling in one place. So unless you want to deal with each potential error individually, try/catch is the simplest and best tool you at your disposal. It works and you can pinpoint the problem:
var w = {}
try {w.x.y.z} catch(e) {e}
TypeError: Cannot read property 'y' of undefined(…)
Alternatively, if you need more control, you could
If it must succeed even if some properties fail, you can check each reference. e.g.:
var sdValid = data &&
data.actions &&
data.actions.length>1 &&
data.actions[0].causes &&
data.actions[0].causes.length &&
data.actions[1].causes[0].shortDescription;
var owner = sdValid
? data.actions[1].causes[0].shortDescription
: 'default value';
this.response = {
owner : owner,
// etc...
}
You can easily make it more readable if you
this.response = {
owner : nestget(data, 'nobody')
.prop('actions', 1)
.prop('causes', 0)
.prop('shortDescription')
.value(),
// return shortDescription if you got this far or 'nobody'
build_version : nestget(data, '0.0.0')
.prop('actions', 0)
.prop('parameters', 0)
.prop('value')
.value(),
// return value if you got this far or '0.0.0'
// ... etc
};
// Custom - easy to use reference checker
function nestget (obj, default) {
var valid = false;
this.default = default;
this.obj = obj;
var that = this;
return {
prop : propChecker,
value : getValue
}
function propChecker (prop, i) {
// implementation omitted for brevity
}
function getValue () {
return value;
}
}
Last but not least, you can always use a library. Personally I like how XPath searches XML trees so I would suggest using something like JSONPath to search for nested objects in a data structure. e.g.
this.response = {
owner : jsonpath(data, '$..shortDescription[0]'),
build_version jsonpath(data, '$.actions[0].parameters[0].value'), // no error
// ... etc
}
However, there are lots of options out there (e.g. lodash/underscore as mentioned in a comment).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With