2017-07-17 52 views
4

是否有某種方法可以刪除或替換EAssertionFailed錯誤消息的絕對路徑?我想不包括整個路徑,不要間接泄露源代碼的編譯位置,並使消息獨立於該位置。優選地,只有項目根目錄或DPR文件的相對路徑或源文件名纔會包含在錯誤消息中。只用相對路徑或文件名刪除或替換EAssertionFailed的絕對路徑?


程序輸出:

EAssertionFailed: Assertion failed (C:\Users\User\Documents\ 
Embarcadero\Studio\Projects\Project3.dpr, line 12) 

Project3.dpr

program Project3; 

{$AppType Console} 

{$R *.res} 

uses 
    System.SysUtils; 

begin 
    try 
    Assert(False); 
    except 
    on E: Exception do 
    begin 
     WriteLn(E.ClassName, ': ', E.Message); 
     ReadLn; 
    end; 
    end; 
end. 
+2

寫自己的處理程序([AssertErrorProc(HTTP:// docwiki.embarcadero.com/Libraries/en/System.AssertErrorProc)),或掛鉤現有的。 – Victoria

回答

3

更換或鉤AssertErrorProc和改變或抑制文件名和行號的信息。

program Project1; 

{$APPTYPE CONSOLE} 

{$R *.res} 

uses 
    System.SysConst, 
    System.SysUtils; 

    procedure CustomAssertErrorHandler(const Message, Filename: string; LineNumber: Integer; ErrorAddr: Pointer); 

    var 
     FileNameOnly : string; 

    begin 
     FileNameOnly := ExtractFileName(FileName); 

     if Message <> '' then 
     raise EAssertionFailed.CreateFmt(SAssertError, 
      [Message, FileNameOnly, LineNumber]) at ErrorAddr 
     else 
     raise EAssertionFailed.CreateFmt(SAssertError, 
      [SAssertionFailed, FileNameOnly, LineNumber]) at ErrorAddr; 
    end; 

begin 
    AssertErrorProc := CustomAssertErrorHandler; 

try 
    Assert(False); 
    except 
    on E: Exception do 
    begin 
     WriteLn(E.ClassName, ': ', E.Message); 
     ReadLn; 
    end; 
    end; 
end. 

更新:下面是提問的解決方案,從整個項目的路徑轉換爲相對路徑:

program Project3; 

{$AppType Console} 

{$R *.res} 

uses 
    System.SysConst, 
    System.SysUtils; 

procedure AssertErrorHandler(const Msg, Filename: String; 
    LineNumber: Integer; ErrorAddr: Pointer); 

{$Region '$Include ProjectRoot.pas.inc'} 

const 
    ProjectRoot = 'C:\Users\'; 

{$EndRegion} 

var 
    Temp: String; 

begin 
    if (ProjectRoot <> '') and Filename.StartsWith(ProjectRoot) then 
    Temp := Filename.Remove(0, ProjectRoot.Length) 
    else 
    Temp := ExtractFileName(Filename); 

    if Msg <> '' then 
    raise EAssertionFailed.CreateResFmt(@SAssertError, 
     [Msg, Temp, LineNumber]) at ErrorAddr 
    else 
    raise EAssertionFailed.CreateResFmt(@SAssertError, 
     [SAssertionFailed, Temp, LineNumber]) at ErrorAddr; 
end; 

begin 
    try 
    AssertErrorProc := AssertErrorHandler; 
// Assert(False); 
    Assert(False, 'Custom message'); 
    except 
    on E: Exception do 
    begin 
     WriteLn(E.ClassName, ': ', E.Message); 
     ReadLn; 
    end; 
    end; 
end. 
+0

好吧,當我編輯答案時,我的意思是將選項集成到一個相對路徑中,並且我的意思是通過CI系統提供項目根路徑,以使問題更全面一些。我接受了原來的答案。但通過審查,我的建議被重新編輯和分開,重複代碼,似乎增加了噪音。所以,對於我來說,是不是我應該在這裏編輯這個呢?我是否要回答我自己的問題? – Max

+0

@Max回答你自己的問題是完全可以接受的。 – Dsm

+0

@Max:是的,您的代碼解決了您的問題中的附加細節。但是,我覺得我的答案更直接,展示您的問題的主要觀點:如何增強/替換'Assert'命令的行爲。您所包含的其他細節可能會讓經驗較少的讀者感到困惑:也許他們可能會認爲CI代碼也是必需的,以便覆蓋「斷言」行爲。 (因此,觸發重複的問題將被髮布)所以,這就是爲什麼我決定單獨包括你的代碼,注意到附加代碼添加到解決方案的什麼... –