Skip to content

Commit

Permalink
Merge pull request #30 from addaleax/errorhandling
Browse files Browse the repository at this point in the history
Error handling
  • Loading branch information
nmrugg committed Nov 9, 2015
2 parents 45da2a2 + 9397a4c commit a69affa
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 103 deletions.
8 changes: 4 additions & 4 deletions readme.md
Expand Up @@ -59,11 +59,11 @@ Create the LZMA object.
/// To compress:
///NOTE: mode can be 1-9 (1 is fast and pretty good; 9 is slower and probably much better).
///NOTE: compress() can take a string or an array of bytes. (A Node.js Buffer counts as an array of bytes.)
my_lzma.compress(string || byte_array, mode, on_finish(result) {}, on_progress(percent) {});
my_lzma.compress(string || byte_array, mode, on_finish(result, error) {}, on_progress(percent) {});

/// To decompress:
///NOTE: The result will be returned as a string if it is printable text; otherwise, it will return an array of signed bytes.
my_lzma.decompress(byte_array, on_finish(result) {}, on_progress(percent) {});
my_lzma.decompress(byte_array, on_finish(result, error) {}, on_progress(percent) {});


Node.js
Expand Down Expand Up @@ -99,9 +99,9 @@ If you'd prefer not to bother with Web Workers, you can just include <code>lzma_

That will create a global <code>LZMA</code> <code>object</code> that you can use directly. Like this:

LZMA.compress(string || byte_array, mode, on_finish(result) {}, on_progress(percent) {});
LZMA.compress(string || byte_array, mode, on_finish(result, error) {}, on_progress(percent) {});

LZMA.decompress(byte_array, on_finish(result) {}, on_progress(percent) {});
LZMA.decompress(byte_array, on_finish(result, error) {}, on_progress(percent) {});

Note that this <code>LZMA</code> variable is an <code>object</code>, not a <code>function</code>.

Expand Down
14 changes: 10 additions & 4 deletions src/lzma.js
Expand Up @@ -8,7 +8,7 @@ if (typeof Worker === "undefined" || (typeof location !== "undefined" && locatio
/// Is this Node.js?
if (typeof global !== "undefined" && typeof require !== "undefined") {
this.LZMA = function (lzma_path) {
return require(lzma_path || "./lzma_worker-min.js").LZMA;
return require(lzma_path || "./lzma_worker.js").LZMA;
};
/// Is this a browser?
} else if (typeof window !== "undefined" && window.document) {
Expand Down Expand Up @@ -73,7 +73,7 @@ if (typeof Worker === "undefined" || (typeof location !== "undefined" && locatio
}());
} else {
/// It doesn't seem to be either Node.js or a browser.
console.log("Can't load the worker. Sorry.");
console.error("Can't load the worker. Sorry.");
}
} else {
/// Let's use Web Workers.
Expand All @@ -96,7 +96,7 @@ if (typeof Worker === "undefined" || (typeof location !== "undefined" && locatio
}
} else {
if (callback_obj[e.data.cbn] && typeof callback_obj[e.data.cbn].on_finish === "function") {
callback_obj[e.data.cbn].on_finish(e.data.result);
callback_obj[e.data.cbn].on_finish(e.data.result, e.data.error);

/// Since the (de)compression is complete, the callbacks are no longer needed.
delete callback_obj[e.data.cbn];
Expand All @@ -106,7 +106,13 @@ if (typeof Worker === "undefined" || (typeof location !== "undefined" && locatio

/// Very simple error handling.
lzma_worker.onerror = function(event) {
throw new Error(event.message + " (" + event.filename + ":" + event.lineno + ")");
var err = new Error(event.message + " (" + event.filename + ":" + event.lineno + ")");

for (var cbn in callback_obj) {
callback_obj[cbn].on_finish(null, err);
}

console.error('Uncaught error in lzma_worker', err);
};

return (function () {
Expand Down
163 changes: 89 additions & 74 deletions src/lzma_worker.js
Expand Up @@ -2453,47 +2453,56 @@ var LZMA = (function () {
on_finish = on_progress = 0;
}

this$static.c = $LZMAByteArrayCompressor({}, encode(str), get_mode_obj(mode));
on_progress = on_progress || function(percent) {
if (typeof cbn == "undefined")
return;

return update_progress(percent, cbn);
};

on_finish = on_finish || function(res, err) {
if (typeof cbn == "undefined")
return;

return postMessage({
action: action_compress,
cbn: cbn,
result: res,
error: err
});
};

if (on_progress) {
try {
this$static.c = $LZMAByteArrayCompressor({}, encode(str), get_mode_obj(mode));

on_progress(0);
} else if (typeof cbn != "undefined") {
update_progress(0, cbn);
} catch (err) {
return on_finish(null, err);
}

function do_action() {
var res, start = (new Date()).getTime();

while ($processChunk(this$static.c.chunker)) {
percent = toDouble(this$static.c.chunker.inBytesProcessed) / toDouble(this$static.c.length_0);
/// If about 200 miliseconds have passed, update the progress.
if ((new Date()).getTime() - start > 200) {
if (on_progress) {
try {
var res, start = (new Date()).getTime();
while ($processChunk(this$static.c.chunker)) {
percent = toDouble(this$static.c.chunker.inBytesProcessed) / toDouble(this$static.c.length_0);
/// If about 200 miliseconds have passed, update the progress.
if ((new Date()).getTime() - start > 200) {
on_progress(percent);
} else if (typeof cbn != "undefined") {
update_progress(percent, cbn);

wait(do_action, 0);
return 0;
}
wait(do_action, 0);
return 0;
}
}

if (on_progress) {

on_progress(1);
} else if (typeof cbn != "undefined") {
update_progress(1, cbn);
}

res = $toByteArray(this$static.c.output);

if (on_finish) {
on_finish(res);
} else if (typeof cbn != "undefined") {
postMessage({
action: action_compress,
cbn: cbn,
result: res
});

res = $toByteArray(this$static.c.output);

/// delay so we don’t catch errors from the on_finish handler
wait(on_finish.bind(null, res), 0);
} catch (err) {
on_finish(null, err);
}
}

Expand All @@ -2514,57 +2523,63 @@ var LZMA = (function () {
on_finish = on_progress = 0;
}

this$static.d = $LZMAByteArrayDecompressor({}, byte_arr);

len = toDouble(this$static.d.length_0);
on_progress = on_progress || function(percent) {
if (typeof cbn == "undefined")
return;

return update_progress(has_progress ? percent : -1, cbn);
};

///NOTE: If the data was created via a stream, it will not have a length value, and therefore we can't calculate the progress.
has_progress = len > -1;
on_finish = on_finish || function(res, err) {
if (typeof cbn == "undefined")
return;

return postMessage({
action: action_decompress,
cbn: cbn,
result: res,
error: err
});
};

if (on_progress) {
on_progress(has_progress ? 0 : -1);
} else if (typeof cbn != "undefined") {
update_progress(has_progress ? 0 : -1, cbn);
try {
this$static.d = $LZMAByteArrayDecompressor({}, byte_arr);

len = toDouble(this$static.d.length_0);

///NOTE: If the data was created via a stream, it will not have a length value, and therefore we can't calculate the progress.
has_progress = len > -1;

on_progress(0);
} catch (err) {
return on_finish(null, err);
}

function do_action() {
var res, i = 0, start = (new Date()).getTime();
while ($processChunk(this$static.d.chunker)) {
if (++i % 1000 == 0 && (new Date()).getTime() - start > 200) {
if (has_progress) {
percent = toDouble(this$static.d.chunker.decoder.nowPos64) / len;
/// If about 200 miliseconds have passed, update the progress.
if (on_progress) {
try {
var res, i = 0, start = (new Date()).getTime();
while ($processChunk(this$static.d.chunker)) {
if (++i % 1000 == 0 && (new Date()).getTime() - start > 200) {
if (has_progress) {
percent = toDouble(this$static.d.chunker.decoder.nowPos64) / len;
/// If about 200 miliseconds have passed, update the progress.
on_progress(percent);
} else if (typeof cbn != "undefined") {
update_progress(percent, cbn);
}

///NOTE: This allows other code to run, like the browser to update.
wait(do_action, 0);
return 0;
}

///NOTE: This allows other code to run, like the browser to update.
wait(do_action, 0);
return 0;
}
}

if (has_progress) {
if (on_progress) {
on_progress(1);
} else if (typeof cbn != "undefined") {
update_progress(1, cbn);
}
}

res = decode($toByteArray(this$static.d.output));

if (on_finish) {
on_finish(res);
} else if (typeof cbn != "undefined") {
postMessage({
action: action_decompress,
cbn: cbn,
result: res
});

on_progress(1);

res = decode($toByteArray(this$static.d.output));

/// delay so we don’t catch errors from the on_finish handler
wait(on_finish.bind(null, res), 0);
} catch (err) {
on_finish(null, err);
}
}

Expand Down
42 changes: 21 additions & 21 deletions test/test-node.js
Expand Up @@ -159,42 +159,42 @@ function decompression_test(compressed_file, correct_filename, next)
}

deco_start = get_hrtime();
try {
my_lzma.decompress(buffer, function (result)
{
my_lzma.decompress(buffer, function (result, e)
{
if (e) {
deco_speed = get_hrtime(deco_start);

console.log("Decompressed size:", result.length + " bytes");

if (typeof result === "string") {
correct_result = correct_result.toString();
}

if (compare(correct_result, result)) {
if (p.basename(correct_filename) === "error-" + e.message) {
display_result("Test passed", true);
console.log("threw correct error: " + e.message);
} else {
display_result("ERROR: files do not match!", false);
display_result("ERROR: " + e.message, false);
all_tests_pass = false;
}

console.log("Decompression time:", deco_speed + " ms");

console.log("");
next();
}, progress);
} catch (e) {
return next();
}
deco_speed = get_hrtime(deco_start);
if (p.basename(correct_filename) === "error-" + e.message) {

console.log("Decompressed size:", result.length + " bytes");

if (typeof result === "string") {
correct_result = correct_result.toString();
}

if (compare(correct_result, result)) {
display_result("Test passed", true);
console.log("threw correct error: " + e.message);
} else {
display_result("ERROR: " + e.message, false);
display_result("ERROR: files do not match!", false);
all_tests_pass = false;
}

console.log("Decompression time:", deco_speed + " ms");

console.log("");
next();
}
}, progress);
});
});
}
Expand Down

0 comments on commit a69affa

Please sign in to comment.