SassDoc / sassdoc

Release the docs!
http://sassdoc.com
MIT License
1.41k stars 56 forks source link

Unable to catch errors when scss parsing fails #539

Open notlee opened 5 years ago

notlee commented 5 years ago

It doesn't appear to be possible to catch a scss parsing error.

E.g. given this scss file which will currently cause a parse error:

/// no semicolon as end of file
/// parsing will fail, although this appears to be valid sass
$a: 1

sassdoc will cause an error which cannot be caught in a try/catch block:

'use strict';
const sassdoc = require('sassdoc');

(async function() {
    try {
        const doclets = await sassdoc('./example-scss', {});
        console.log({doclets});
    } catch (error) {
        // this is never reached
        console.log('sassdoc failed to generate doclets: ' + error.message);
    }
})();
Screenshot 2019-08-12 at 17 07 02

I believe this may be because the error is from a stream, and the through callback isn't called around here?

notlee commented 5 years ago

Here's a diff which I think would solve the problem. Happy to PR if you agree 😄

diff --git a/src/parser.js b/src/parser.js
index c00d04b..ceb71f8 100644
--- a/src/parser.js
+++ b/src/parser.js
@@ -60,8 +60,6 @@ export default class Parser {
     let data = []

     let transform = (file, enc, cb) => {
-      // Pass-through.
-      cb(null, file)

       let parseFile = ({ buf, name, path }) => {
         let fileData = this.parse(buf.toString(enc), name)
@@ -76,21 +74,27 @@ export default class Parser {
         })
       }

-      if (file.isBuffer()) {
-        let args = {
-          buf: file.contents,
-          name: path.basename(file.relative),
-          path: file.relative,
+      try {
+        if (file.isBuffer()) {
+          let args = {
+            buf: file.contents,
+            name: path.basename(file.relative),
+            path: file.relative,
+          }
+          parseFile(args)
         }

-        parseFile(args)
+        if (file.isStream()) {
+          file.pipe(concat(buf => {
+            parseFile({ buf })
+          }))
+        }
+      } catch (error) {
+        cb(error);
       }

-      if (file.isStream()) {
-        file.pipe(concat(buf => {
-          parseFile({ buf })
-        }))
-      }
+      // Pass-through.
+      cb(null, file)
     }

     let flush = cb => {
pascalduez commented 5 years ago

Hi @notlee,

yes, that seems like reasonable addition ;)