node-7z icon indicating copy to clipboard operation
node-7z copied to clipboard

Feature Request: Emit error on early 7z process termination

Open sysrage opened this issue 4 years ago • 9 comments

Currently, if the spawned 7-zip process is killed before extraction is complete, the 'end' event is emitted and no errors are shown. Since the extraction actually failed in this case, an 'error' event should be emitted instead.

If there's some technical reason this shouldn't be fixed, please update documentation to suggest that people implement their own error handling for this corner-case. Something like:

extractStream.on('end', () => {
  if (!extractStream.info.Compressed) {
    return reject(new Error('7za Process Terminated Early'));
  }
  resolve();
});

extractStream.on('error', (error) => {
  reject(error);
});

sysrage avatar Aug 05 '21 01:08 sysrage

It looks like the above workaround doesn't even work. Sometimes extracStream.info.Compressed exists and sometimes it doesn't. Why doesn't this always exist when the 'end' event is fired and extraction was complete?

sysrage avatar Aug 05 '21 02:08 sysrage

Which method do you use for killing the process? Ctrl+C ?

q2s2t avatar Aug 05 '21 16:08 q2s2t

For my initial testing, I was clicking 'End Process' in Task Manager. Based on your question, I'll see if other termination signals result in a properly emitted error!

Or not...

taskkill /im 7za.exe
ERROR: The process "7za.exe" with PID 51192 could not be terminated.
Reason: This process can only be terminated forcefully (with /F option)

sysrage avatar Aug 05 '21 16:08 sysrage

Can you help me understand why extractStream.info is intermittently missing several properties when the 'end' event is emitted after a successful extract?

This is what I see after successfully extracting one file:

extractStream.info Map(9) {
  '7-Zip (a) 19.00 (x64) ' => 'Copyright (c) 1999-2018 Igor Pavlov : 2019-02-21',
  'Extracting archive' => 'C:\\SomeDirectory\\myarchive.7z',
  'Path' => 'C:\\SomeDirectory\\myarchive.7z',
  'Type' => '7z',
  'Physical Size' => '3283117249',
  'Headers Size' => '1340',
  'Method' => 'LZMA2:30 LZMA:20 BCJ2',
  'Solid' => '+',
  'Blocks' => '11'
}

This is what I see when extracting another file:

extractStream.info Map(13) {
  '7-Zip (a) 19.00 (x64) ' => 'Copyright (c) 1999-2018 Igor Pavlov : 2019-02-21',
  'Extracting archive' => 'C:\\SomeDirectory\\myarchive2.7z',
  'Path' => 'C:\\SomeDirectory\\myarchive2.7z',
  'Type' => '7z',
  'Physical Size' => '1462534299',
  'Headers Size' => '19534',
  'Method' => 'LZMA2:24 LZMA:19 BCJ2',
  'Solid' => '+',
  'Blocks' => '3',
  'Folders' => '5',
  'Files' => '2907',
  'Size' => '1524469438',
  'Compressed' => '1462534299'
}

Why are Folder, Files, Size, and Compressed missing?

sysrage avatar Aug 05 '21 17:08 sysrage

So, the above behavior is not specific to a particular archive. It appears to be a timing issue, as the same archive file will contain proper info data sometimes but not every time. If I have other disk I/O active while the extraction is in progress, it seems to increase the time between the 'end' event is emitted and the info map is fully populated.

sysrage avatar Aug 06 '21 00:08 sysrage

Thanks for the thumbs-up on the previous comment, but can you please provide any input on anything reported?

Related to this issue, is there any method currently available for either of the following?

  • Obtaining the PID of the 7-zip process that was launched to extract the file. This could be used elsewhere to kill said process, when an abort signal is received, rather than killing all 7za processes.
  • Cancelling the extraction when some sort of abort signal is emitted. This could be either an AbortController implementation or something like axios' cancelToken implementation.

I'm attempting to use this package for a project that will be extracting very large archives and want to allow users to cancel, if necessary.

EDIT: After posting this, I realized I can likely use $childProcess so I know the PID, but that's not very convenient. Would it be possible to add the 7-zip PID to stream.info for easy access when not using $childProcess? Even better would be an integrated abort implementation!

sysrage avatar Aug 12 '21 01:08 sysrage

I will work on that in the next few weeks (no access to a computer for now)

q2s2t avatar Aug 12 '21 18:08 q2s2t

Can @sysrage confirm that commit e961ac4 fixes the issue?

q2s2t avatar Feb 06 '22 19:02 q2s2t

Using commit https://github.com/quentinrossetti/node-7z/commit/e961ac49d67f6f09ed8937ae6e24770833f64838, the original issue still exists. No error event is emitted if the 7-zip process is killed during extraction. The end event is emitted, as-if there were no errors. So, I still submit a request to emit an error event if the 7-zip process ends unexpectedly.

Additionally, the extractStream.info property seems to always be missing the Folder, Files, Size, and Compressed properties now. As mentioned above, with the released build it would intermittently include these properties upon successful extraction.

Support for an AbortController or some other cancellation method would also still be very useful.

sysrage avatar Feb 07 '22 01:02 sysrage