Pārlūkot izejas kodu

Cleanup error messages and logging.

Martijn Laan 3 mēneši atpakaļ
vecāks
revīzija
794185163e
1 mainītis faili ar 59 papildinājumiem un 39 dzēšanām
  1. 59 39
      Projects/Src/Compression.SevenZipDLLDecoder.pas

+ 59 - 39
Projects/Src/Compression.SevenZipDLLDecoder.pas

@@ -320,8 +320,8 @@ end;
 
 function TArchiveExtractCallback.GetProperty(const index: UInt32;
   const propID: PROPID; const allowedTypes: TVarTypeSet; out value: OleVariant): Boolean;
-{ Raises an exception on error but otherwise always sets value, returning True if
-  it's not empty }
+{ Raises an EOleSysError exception on error but otherwise always sets value,
+  returning True if it's not empty }
 begin
   var Res := FInArchive.GetProperty(index, propID, value);
   if Res <> S_OK then
@@ -463,6 +463,22 @@ begin
   Result := Assigned(CreateSevenZipObject);
 end;
 
+procedure SevenZipError(const LogMessage, ExceptMessage: String);
+{ Do not call from secondary thread. LogMessage may contain non-localized text
+  ExceptMessage should not. }
+begin
+  LogFmt('ERROR: %s', [LogMessage]); { Just like 7zMain.c }
+  raise Exception.Create(ExceptMessage);
+end;
+
+procedure SevenZipWin32Error(const FunctionName: String; LastError: DWORD = 0); overload;
+begin
+  if LastError = 0 then
+    LastError := GetLastError;
+  const Msg = Format('%s (%u)', [Win32ErrorString(LastError), LastError]);
+  SevenZipError(Format('%s failed: %s', [FunctionName, Msg]), Msg);
+end;
+
 function ExtractThreadFunc(Parameter: Pointer): Integer;
 begin
   const E = TArchiveExtractCallback(Parameter);
@@ -576,7 +592,7 @@ procedure ExtractArchiveRedir(const DisableFsRedir: Boolean;
       kHeadersError: Result := 'Headers error';
       kWrongPassword: Result := 'Wrong password';
     else
-      Result := Format('Unknown result %d', [Ord(opRes)]);
+      Result := Format('Unknown operation result: %d', [Ord(opRes)]);
     end;
   end;
 
@@ -588,17 +604,15 @@ procedure ExtractArchiveRedir(const DisableFsRedir: Boolean;
         Msg := (Result.SavedFatalException as Exception).Message
       else
         Msg := Result.SavedFatalException.ClassName;
-      raise Exception.Create(FmtSetupMessage(msgErrorExtractionFailed, [Msg]));
+      SevenZipError(Format('Worker thread terminated unexpectedly with exception: %s', [Msg]), Msg);
     end else if Result.Res = E_ABORT then
-      raise Exception.Create(SetupMessages[msgErrorExtractionAborted])
+      Abort
     else begin
       var OpRes := Result.OpRes;
-      if OpRes <> kOK then begin
-        LogFmt('ERROR: %s', [OperationResultToString(Result.OpRes)]); { Just like 7zMain.c }
-        raise Exception.Create(FmtSetupMessage(msgErrorExtractionFailed, [Ord(OpRes).ToString]))
-      end else if Result.Res <> S_OK then
-        raise Exception.Create(FmtSetupMessage(msgErrorExtractionFailed,
-          [Format('%s %s', [Win32ErrorString(Result.Res), IntToHexStr8(Result.Res)])]));
+      if OpRes <> kOK then
+        SevenZipError(OperationResultToString(Result.OpRes), Ord(OpRes).ToString)
+      else if Result.Res <> S_OK then
+        SevenZipWin32Error('Extract', Result.Res);
     end;
   end;
 
@@ -614,11 +628,8 @@ procedure ExtractArchiveRedir(const DisableFsRedir: Boolean;
 
     var ThreadID: TThreadID; { Not used but BeginThread requires it }
     const ThreadHandle = BeginThread(nil, 0, ExtractThreadFunc, E, 0, ThreadID);
-    if ThreadHandle = 0 then begin
-      const LastError = GetLastError;
-      raise Exception.Create(FmtSetupMessage(msgErrorExtractionFailed,
-        [Format('%s %s', [Win32ErrorString(LastError), IntToHexStr8(LastError)])]));
-    end;
+    if ThreadHandle = 0 then
+      SevenZipWin32Error('BeginThread');
 
     try
       while True do begin
@@ -626,7 +637,7 @@ procedure ExtractArchiveRedir(const DisableFsRedir: Boolean;
           WAIT_OBJECT_0: Break;
           WAIT_TIMEOUT: HandleProgress(E);
         else
-          raise Exception.Create(FmtSetupMessage(msgErrorExtractionFailed, ['WaitForSingleObject failed']));
+          SevenZipWin32Error('WaitForSingleObject');
         end;
       end;
     finally
@@ -649,30 +660,39 @@ begin
 
   LogFmt('%s Decoder : Igor Pavlov', [SetupHeader.SevenZipLibraryName]); { Just like 7zMain.c }
 
-  { CreateObject }
-  var InArchive: IInArchive;
-  if CreateSevenZipObject(clsid, IInArchive, InArchive) <> S_OK then begin
-    Log('ERROR: Cannot get class object'); { Just like 7zMain.c and Client7z.cpp }
-    raise Exception.Create(FmtSetupMessage(msgErrorExtractionFailed, ['-1']));
-  end;
+  try
+    { CreateObject }
+    var InArchive: IInArchive;
+    if CreateSevenZipObject(clsid, IInArchive, InArchive) <> S_OK then
+      SevenZipError('Cannot get class object' { Just like Client7z.cpp }, '-1');
 
-  { Open }
-  const InStream: IInStream =
-    TInStream.Create(TFileRedir.Create(DisableFsRedir, ArchiveFilename, fdOpenExisting, faRead, fsRead));
-  var ScanSize: Int64 := 1 shl 23; { From Client7z.cpp }
-  const OpenCallback: IArchiveOpenCallback = TArchiveOpenCallback.Create(Password);
-  if InArchive.Open(InStream, @ScanSize, OpenCallback) <> S_OK then begin
-    Log('ERROR: Cannot open file as archive'); { Just like 7zMain.c and Client7z.cpp }
-    raise Exception.Create(FmtSetupMessage(msgErrorExtractionFailed, ['-2']));
+    { Open }
+    var F: TFile := nil; { Set to nil to silence compiler }
+    try
+      F := TFileRedir.Create(DisableFsRedir, ArchiveFilename, fdOpenExisting, faRead, fsRead);
+    except
+      SevenZipWin32Error('CreateFile');
+    end;
+    const InStream: IInStream =
+      TInStream.Create(F);
+    var ScanSize: Int64 := 1 shl 23; { From Client7z.cpp }
+    const OpenCallback: IArchiveOpenCallback = TArchiveOpenCallback.Create(Password);
+    if InArchive.Open(InStream, @ScanSize, OpenCallback) <> S_OK then
+      SevenZipError('Cannot open file as archive' { Just like Client7z.cpp }, '-2');
+
+    { Extract }
+    const ExtractCallback: IArchiveExtractCallback =
+      TArchiveExtractCallback.Create(InArchive, DisableFsRedir,
+        ArchiveFilename, DestDir, Password, FullPaths, OnExtractionProgress);
+    Extract(ExtractCallback as TArchiveExtractCallback);
+
+    Log('Everything is Ok'); { Just like 7zMain.c }
+  except
+    on E: EAbort do
+      raise Exception.Create(SetupMessages[msgErrorExtractionAborted])
+    else
+      raise Exception.Create(FmtSetupMessage(msgErrorExtractionFailed, [GetExceptMessage]));
   end;
-
-  { Extract }
-  const ExtractCallback: IArchiveExtractCallback =
-    TArchiveExtractCallback.Create(InArchive, DisableFsRedir,
-      ArchiveFilename, DestDir, Password, FullPaths, OnExtractionProgress);
-  Extract(ExtractCallback as TArchiveExtractCallback);
-
-  Log('Everything is Ok'); { Just like 7zMain.c }
 end;
 
 end.