Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error handling #95

Merged
merged 3 commits into from
Jan 15, 2017
Merged

Error handling #95

merged 3 commits into from
Jan 15, 2017

Conversation

jacekkopecky
Copy link
Contributor

This addresses #93 and other issues found in course of fixing that. I'll add comments in the source about the various changes.

The changes in test/middleware.js are so that I could run the tests repeatedly – as it was, the test would start the example server but never kill it, so the next time tests run, EADDRINUSE would be thrown.


sassMiddlewareError = err;
};

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

moved error() here so sass() is reentrant.

added logging of all errors if debugging is on


error(err, errorMessage);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

moved logging into error(); stopped overloading the data variable.

return error(err);
error(err);
cssDone = true;
return doneWriting();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as it was, in case of errors here, next() would never be called and the request would just hang there. We need to call doneWriting.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we add an option to toggle propagation to next middleware in case of error? My concern is someone might have taken dependency on this behavior by now and this would break them.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem is that nothing calls next() and nothing touches req after this point, so the request is left to time out.

Even if someone supplies options.error and we call them, they don't have access to req or next, so they can't do anything with the request.

In most other places, the call to error() is followed by next(), but not here; I can't imagine right now what dependency on this behaviour someone might have taken – can you please illustrate what you mean?

Propagating to the next middleware in case of error is the expected behaviour – we are a middleware after all.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense.

can you please illustrate what you mean?

For instance, some consumer might be reading the error and not existing as Sass middle ware is existing the pipeline for them.

With that being said, I don't have strong feelings about it. Consistent behavior wins. Thanks for elaboration. :)

}

fs.writeFile(cssPath, data, 'utf8', function(err) {
if (err) {
return error(err);
error(err);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above

}

fs.writeFile(sourceMapPath, result.map, 'utf8', function(err) {
if (err) {
return error(err);
error(err);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

both same as the above

@@ -265,18 +269,18 @@ module.exports = function(options) {

// Compare mtimes
fs.stat(sassPath, function(err, sassStats) {
if (err) {
error(err);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's not really an error if we can't stat sassPath

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If sassPath doesn't exist then consumer of sass middleware must have wrong input path provider. Error/fail fast is the current behavior, this is intentional?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I understand the code right, sassPath is computed from the request – it's the path to the potentially existing .scss file which, if it's there and younger than the .css file, will trigger compilation. Notice in the original code the error is logged with error(err) but then we just let next() handle the request.

Inside compile(), which gets called after this code, we check that sassPath fs.exists - that seems redundant now; or it indicates I don't quite get what's going on.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that seems redundant now

Actually, this check is bit redundant because compile() has other callsites where we are not ensuring whether the file exists. We should error out (or log with debug severity) in compile function instead.

But lets keep it as is for now; I am planning to but some debug logs here and other places with new tag skip, to indicate that middleware recognized the request but since it can't fetch file stat, skipping to next. The issue #88 will ultimately get fixed once we also log a message and skip to next middleware when middleware receives a mismatching prefixed request (in case user has used the prefix option); so in the OP's example outdatedbrowser.min.css will not match the prefix, hence we skip to next middleware but still debug log that we (the middleware) saw the request and skipping to next due to such and such reasons.

This will help consumer debugging.

if (debug) { log('error', 'not found', cssPath); }
if (err) {
if ('ENOENT' === err.code) { // CSS has not been compiled, compile it!
if (debug) { log('debug', 'not found', cssPath); }
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not finding the CSS file is common, not really an error - it happens before the first compilation

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree the message can probably say: "not found , compiling .."

return compile();
}

error(err);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

give this error to options.error - that seems to be the expectation

Copy link
Collaborator

@am11 am11 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Few comments / questions. Overall looks good. Thanks @jacekkopecky for doing this and especially for writing the tests! 👍

return error(err);
error(err);
cssDone = true;
return doneWriting();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we add an option to toggle propagation to next middleware in case of error? My concern is someone might have taken dependency on this behavior by now and this would break them.

@@ -265,18 +269,18 @@ module.exports = function(options) {

// Compare mtimes
fs.stat(sassPath, function(err, sassStats) {
if (err) {
error(err);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If sassPath doesn't exist then consumer of sass middleware must have wrong input path provider. Error/fail fast is the current behavior, this is intentional?

if (debug) { log('error', 'not found', cssPath); }
if (err) {
if ('ENOENT' === err.code) { // CSS has not been compiled, compile it!
if (debug) { log('debug', 'not found', cssPath); }
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree the message can probably say: "not found , compiling .."

@am11 am11 merged commit 3ef0775 into sass:master Jan 15, 2017
@am11
Copy link
Collaborator

am11 commented Jan 15, 2017

Thanks again @jacekkopecky ! 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants