我有几个数据库访问方法包含在try / catch块中:
function GetAll() {
try {
entityLoad("Book");
}
catch (any e) {
throw (type="CustomException", message="Error accessing database, could not read");
}
}
function Save(Book book) {
try {
entitySave(book);
}
catch (any e) {
throw (type="CustomException", message="Error accessing database, could not save);
}
}
正如您所看到的,try / catch块会重复多次,其中唯一不同的是消息。是否可以在ColdFusion中创建委托,以便我可以做这样的事情(使用C#lambda来表示匿名委托)?:
function GetAll() {
DatabaseOperation(() => entityLoad("Book"), "could not read");
}
function Save(Book book) {
DatabaseOperation(() => entitySave(book), "could not save");
}
function DatabaseOperation(delegate action, string error) {
try {
action.invoke();
}
catch (any e) {
var message = "Error accessing database, " & error;
throw (type="CustomException", message=message);
}
}
答案 0 :(得分:6)
基于您的示例,而不是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
- 似乎没有用来掩盖原始错误而是抛出更通用的错误?
更新:还有两种可能的选择......
当前有效的另一个选项是拥有一个公共包装函数,它调用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);
}
}