Hello there,
Can I use a try … catch block with in a single job
My scenario
I’m using the http adaptor to try and add data to akeneo, which has variables set up as option lists
what I’m looking for is something like
get("www.example.com/1"); // header params
.
.
try {
// check if variable exists
fn(state => {
var x = state.references[0].x.toLowerCase().trim();
return get(`.../attributes/x/options/${x}`); // returns a 404 if it doesn't exist
});
} catch (error) {
post(`.../attributes/x/options`, {
body: state => {
return {
"code": state.references[0].x.toLowerCase().trim(),
"value": state.references[0].x
};
},
header: state => {
return {
"y": state.references[1].y
};
},
}); // create the option
}
Which I run for 8 more variables before finally adding the product with the variables set to their respective options
Problem is, state in the catch clause resets to initial state (empty references and data is one received in inbox)
also, Is this the right approach to creating a job like this?
1 Like
Very cool concept @etdvlpr !
(cc: @Mamadou , @stu in case you have anything to add)
A few suggestions:
-
At the time of writing, you can’t use try/catch
at the top level like that. Everything at the top level needs to be an operation. Also, as a general rule of thumb, your custom Javascript should go inside an fn
operation.
-
Most of the functions that you’d commonly use at the top level will expect to be called with state
… so if you use them inside a custom fn
block, you’ll need to do so. For example, return get('url');
should become return get('url')(state)
if you want to execute it inside an fn
block.
-
The “OpenFn way” of doing this would likely be with promises, making use of .then()
, .catch()
, and .finally()
. Consider the code (with some of your data transformation commented out) below:
get('https://jsonplaceholder.typicode.com/todos/1'); // header params
// check if variable exists
fn(state => {
// var x = state.references[0].x.toLowerCase().trim();
console.log('Trying to get some more data...');
// returns a 404 if it doesn't exist
return get(`https://jsonplaceholder.typicode.com/comments/501`)(state)
.catch(error => {
console.log('But failing with...', error.response.status);
// create the option
return post(`https://jsonplaceholder.typicode.com/comments`, {
body: {
// code: state.references[0].x.toLowerCase().trim(),
// value: state.references[0].x,
},
// header: { y: state.references[1].y },
})(state);
})
.then(result => result)
.finally(result => result);
});
- This is a small thing, but once you’re inside that
fn
block and making your post
to “create the option” you can access parts of state
directly, rather than through a function. When using these helper operations (like get
, post
, or createPatient
) directly, OpenFn’s “magic” is knowing when to evaluate state. But inside a custom fn
block you’re on your own… so if you define state
on line 4, you’ll be plucking out state.references of that state when you ask for it later in your code block.
This last point is definitely a subtle one, but the guiding principal is that inside an open fn
block, you’re writing code and doing exactly what you want… no magic (or interference) from core.
I guess my java experience got the better of me.
Thanks, it’s working brilliantly.
1 Like