当我在一个Transactional Data Module(SOrder)中调用另一个Transactional Data Module(UpdateStock)时,无法获得updatestock抛出的错误:
SOrder:
var
upstk:iupdatestock;
begin
olecheck(datamod.ObjectContext.CreateInstance,CLASS_UpdateStock,IID_IUpdateStock,upstk));
try
upstk.method1(orderID,updatestock_s.UPDATE_OUTSTOCK);
except
on e:eoleexception do logtofile(e.message);
end;
end;procedure UpdateStock.method1(....)
begin
//.....do something
if (hasError) then raise EOleException.create('库存不足',.....);
end;可是在调用方只能抓到'灾难性故障';
请问如何才能获得UpdateStock.method1抛出的错误信息

解决方案 »

  1.   

    在UpdateStock.method1里面 try 行吗?
      

  2.   

    to myling(阿德):
    谢谢,在UpdateStock.method1里面 try 可以,但调用过程是client-->sorder(com+)-->updatestock.method1,错误信息要从method1-->sorder-->client。主要是错误信息如何返回的问题
      

  3.   

    你设一个属性
    出错时写入这个属性
    CLIENT读取这个属性性就知道出什么问题了
      

  4.   

    把函数返回值设置成WordBool,加一个out参数返回错误信息即可。
      

  5.   

    谢谢大家的提议,可是我希望有比较系统的解决方法。好象有IErrorInfo,可是我不知道如何使用,还希望大家赐教,如果加一个参数返回,好象不是结构性的。因为我以前是做java的在java里面可以很容易的定义错误并返回。object1.method1(..){
     try{
       object2.method2(...);
      }catch(StockLackException e){
        //do something....
      }catch(DuplicateKeyException e){
       //do something....
      }
    }object2.method2(...){
      //do something...
      if (lack){
       throws new StockLackException('库存不足');
      }
      if (dublicatekey){
       throws new DubliceatekeyException('主键重复');
      }
    }我们大家多多讨论。
      

  6.   

    SOrder:begin
      ……
      try
        upstk.method1(orderID,updatestock_s.UPDATE_OUTSTOCK);
      except
        on e:eoleexception do logtofile(e.message);
        raise;     //  在这里重新抛出异常,  客户端能够捕获
      end;
    end;IErrorInfo 等处理错误的接口已经被封装到 Delphi 的 safecall 异常处理中了,不用你自己实现。
      

  7.   

    com+ 错误用delphi可以正常捕获, BCB...让人无奈ing, IErrorInfo 不知从哪获得...顺便指证一个超极错误(datamod.ObjectContext.CreateInstance,CLASS_UpdateStock,IID_IUpdateStock,upstk));
     ^^^^^^^^
    这是什么东东??, 是一个全局变量!! 两个用户(线程)在同时访问时 datamod 指得是哪个线程?? 哪怕你用 self. 也好
      

  8.   

    To Comanche
    谢谢,但这段代码是在一个ActionObject里面(主要是为了实现系统多样性),所以会把datamodule传入。
      

  9.   

    to leapmars(流铭):
    如果是client-->com+你说的是对的,但client-->com+1-->com+2,com+1 try不道com+2的exception,只能抓到'灾难性故障'
      

  10.   

    我仔细看过了, 
    delphi 如果没有 safecall 得到错误内容的方法是 OleError(HRESULT), 一切正常但 BCB, 得到却得到 '服务器发生意外'
      

  11.   

    我的method1是safecall啊。
    定义在xxx_TLB.pas
    IUpdateStock = interface(IAppserver)
        ['{587B82DC-82C1-49DB-9F2B-CC48350D133D}']
    procedure method1(const orderID: WideString; UpdateKind: Integer); safecall;
    end;
      

  12.   

    我的方法:
    com+1
    tryexcept
     raise;
    end;
    com+2
    tryexcept
     raise;
    end;
    这样的话client-->com+1-->com+2,错误就会从com+2里逐步传递出来。
      

  13.   

    procedure 怎样返回hresult呢?难道method1(xxx,xxx,int* hresult)?
      

  14.   

    你的 datamod 的事务模型是?我也在试你的东东, 发现以下总是得到 "灾难性失败"// 这里没什么问题
    procedure TTransStarter.Action;
    var
      Trans :ITransactionContextEx;
      Category :ICategory; // 这两个是用 MSSQL2000 的 Northwind 的两个表
      Product :IProduct;
    begin
      Trans := CreateTransactionContextEx;
      try
        OleCheck(Trans.CreateInstance(CLASS_Category, ICategory, Category));
        OleCheck(Trans.CreateInstance(CLASS_Product, IProduct, Product));    Category.Action('Hello world');
        Product.Action('Hello world');
        SetComplete;
      except
        Trans.Abort;
        raise;
      end;
    end;// 这里有错, ICategory 实现跟这基本一样
    procedure TProduct.Action(const ProductName: WideString);
    begin
      try
        with InsertCmd, InsertCmd.Parameters do
        begin
          ParamValues['ProductName'] := ProductName;
          Execute;
        end;    raise Exception.Create('hello except from trans'); // 有意
        SetComplete;
      finally
    //    SetAbort; 如果这个用 DisableCommit 代替就正常
        raise;
      end;
    end;
      

  15.   

    finally // 这个不是 finally 是 except
    //    SetAbort; 如果这个用 DisableCommit 代替就正常
        raise;
      end;
      

  16.   

    刚才我试了一下,应该没什么问题呀
    client-->com+1-->com+2,  com+1 应该 try 得到 com+2 的 exception
      

  17.   

    // 这是 com+1type
      TObj1 = class(TMtsAutoObject, IObj1)
      protected
        procedure Method1; safecall;
      end;procedure TObj1.Method1;
    var
      Intf: IObj2; 
    begin
      try
        Intf := CoObj2.Create;
        Intf.Method2;
        SetComplete;
      except
        on Exception do
        begin
          SetAbort;
          raise;
        end;
      end;
    end;// 这是 com+2type
      TObj2 = class(TMtsAutoObject, IObj2)
      protected
        procedure Method2; safecall;
      end;procedure TObj2.Method2;
    begin
      try
        raise Exception.Create('TObj2.Method2 Exception');
        SetComplete;
      except
        on Exception do
        begin
          SetAbort;
          raise;
        end;
      end;
    end;// clientprocedure TForm3.Button1Click(Sender: TObject);
    var
      Intf: IObj1;
    begin
      Intf := CoObj1.Create;
      Intf.Method1;
    end;
      

  18.   

    注意此时 raise; 一定要在 SetAbort; 之后,否则就是“灾难性故障”!
      

  19.   

    to leapmars(流铭) 
    try的到exception,但拿不到详细信息
      

  20.   

    to leapmars(流铭) 
     raise; 一定在 SetAbort; 之后,
      

  21.   

    to comanche(太可怕) 
    我的datamodule是事务模型
      

  22.   

    哎,俺每次得到的是-----  ole error 80040e14
    就是不能捕捉到数据库的raiserror
    谁有办法?
      

  23.   

    拿不到详细信息吗?不会吧client 可以显示 com+2 的异常信息呀 “TObj2.Method2 Exception”
      

  24.   

    to comanche(太可怕) 
    谢谢,用 DisableCommit 代替就正常了,WHY?
    谢谢,用 DisableCommit 代替就正常了,WHY?
    谢谢,用 DisableCommit 代替就正常了,WHY?
    谢谢,用 DisableCommit 代替就正常了,WHY?散分了,谢谢大家。
    散分了,谢谢大家。
    散分了,谢谢大家。
      

  25.   

    晕结了, 跟到 http://expert.csdn.net/Expert/topic/1926/1926924.xml?temp=.5555689