// TODO: Refactor allowErrors logic so that it's actually part of the internal $getProperty implementation in dlayer itself, and this abstraction uses that tool?
// TODO: Refactor allowErrors logic so that it's actually part of the internal $getProperty implementation in dlayer itself, and this abstraction uses that tool?
// The AllowErrors option is set when a source definition has its own way to deal with (allowable) errors. Instead of simply propagating the error for all affected attributes, it calls the attribute handlers with the Result (or returns `undefined` if only a property is specified).
if(dataSource==null){
// TODO: How to deal with null results? Allow them or not? Make it an option?
thrownewError(`Attempted to read from context property '${source}', but no such property exists`);
if(result.isOK&&result.value()==null){
}elseif(sourceID==null){
// TODO: Change implementation to allow `Result.ok(null|undefined)` but not `null|undefined` directly?
// FIXME: Better error message
thrownewError(`Null-ish result returned for ID ${util.inspect(properties[ID])} from source at context property '${source}'; this is not allowed, and there is probably a bug in your code. Please file a ticket if you have a good usecase for null-ish results!`);
// This is equivalent to a `throw`, and so we just propagate it
returnresult;
}
}else{
// This is to support property name shorthand used in place of a selector function
if(typeofselector==="string"){
returnresult.value()[selector];
}else{
returnselector(result.value(),context);
}
}
});
};
return[property,getter];
});
}),
(_)=>Object.fromEntries(_)
]);
// NOTE: We always specify the generated properties first, so that properties can be overridden by explicit known values to bypass the source lookup, if needed by the implementation
return{
...generatedProperties,
...rest
};
},
ID:ID,
AllowErrors:AllowErrors
};
// The AllowErrors option is set when a source definition has its own way to deal with (allowable) errors. Instead of simply propagating the error for all affected attributes, it calls the attribute handlers with the Result (or returns `undefined` if only a property is specified).
// TODO: How to deal with null results? Allow them or not? Make it an option?
if(result.isOK&&result.value()==null){
// TODO: Change implementation to allow `Result.ok(null|undefined)` but not `null|undefined` directly?
thrownewError(`Null-ish result returned for ID ${util.inspect(properties[ID])} from source at context property '${source}'; this is not allowed, and there is probably a bug in your code. Please file a ticket if you have a good usecase for null-ish results!`);
}elseif(allowErrors===true&&isCustomSelector){
// Custom selectors always receive the Result as-is (note that this has to come before the error case handling!)
returnselector(result,context);
}elseif(result.isError){
if(allowErrors===true){
// TODO: Does this actually make sense?
returnundefined;
}else{
// This is equivalent to a `throw`, and so we just propagate it
returnresult;
}
}elseif(isCustomSelector){
returnselector(result.value(),context);
}else{
// This is to support property name shorthand used in place of a selector function