На основе вашего примера, а не с CF9.
В CF10 идут закрытия, которые, вероятно, позволят вам сделать что-то вроде:
function GetAll() {
DatabaseOperation( closure(){ entityLoad("Book") } , "could not read");
}
function Save(Book book) {
DatabaseOperation( closure(){ entitySave(book) } , "could not save");
}
function DatabaseOperation(closure action, string error) {
try {
action();
}
catch (any e) {
var message = "Error accessing database, " & error;
throw (type="CustomException", message=message);
}
}
(синтаксис может отличаться, непомните, если это было именно так)
В качестве альтернативы, вы могли бы использовать evaluate
здесь, я думаю ...
function GetAll() {
DatabaseOperation( 'entityLoad("Book")' , "could not read");
}
function Save(Book book) {
DatabaseOperation( 'entitySave(book)' , "could not save");
}
function DatabaseOperation(string action, string error) {
try {
evaluate(action);
}
catch (any e) {
var message = "Error accessing database, " & error;
throw (type="CustomException", message=message);
}
}
Лично я бы просто удалил try / catch и использовал onError
в Application.cfc
- кажется, бесполезно маскировать исходную ошибку и вместо этого выдавать более общую ошибку?
Обновление: еще две возможные альтернативы ...
Другой вариант, который в настоящее время работает, - это иметь функцию-обертку public, которая вызывает функцию DatabaseOperation, передавая имя частной функции, которая выполняетфактическая логика, как это:
function GetAll() {
DatabaseOperation( real_GetAll , Arguments , "could not read");
}
private function real_GetAll() {
entityLoad("Book")
}
function Save(Book book) {
DatabaseOperation( real_Save , Arguments , "could not save");
}
private function real_Save(Book book) {
entitySave(book)
}
function DatabaseOperation(any action, struct args , string error) {
try {
action( argumentcollection=args )
}
catch (any e) {
var message = "Error accessing database, " & error;
throw (type="CustomException", message=message);
}
}
Если вам не нравится идея определения функций дважды, но вы не против скрыть API, вы можете установить методы как private, а затем использовать onMissingMethod:
private function GetAll()
{
entityLoad("Book")
}
private function Save(Book book)
{
entitySave(book)
}
function onMissingMethod( string MethodName , struct MethodArgs )
{
if ( NOT StructKeyExists(Variables,Arguments.MethodName) )
{
throw("The method #Arguments.MethodName# was not found");
}
try
{
var Meth = Variables[Arguments.MethodName];
Meth( ArgumentCollection=Arguments.MethodArgs );
}
catch(any e)
{
var message = "Error accessing database, ";
switch(MethodName)
{
case "GetAll":
message &= "could not read";
break;
case "Save":
message &= "could not save";
break;
}
throw (type="CustomException,message=message);
}
}