Repository: tldr-pages/tldr-node-client (js)

Issue:
tldr fails silently when trying to read invalid `.tldrrc` leading to confusion
I come from here: https://github.com/tldr-pages/tldr/issues/1262

https://github.com/tldr-pages/tldr-node-client/blob/1641dea94df3aabcd36f381dcac61a50905a36ea/lib/config.js#L16-L21

There should be some error printed on error stream that the JSON object couldn't be loaded due to invalid syntax. JSON parse fails silently when the file is missing (that's OK), but SHOULD error when the config is invalid. Common examples when `*rc` files print errors include `.vimrc`, `.tmux.conf` and probably others.

The simplest case - yeet the ESlint directives and add proper error handling.

Pull request:
Show error on failing to parse .tldrrc
## Description
Fixes #365 

## Checklist

Please review this checklist before submitting a pull request.

- [x] Code compiles correctly
- [x] Created tests, if possible
- [x] All tests passing (`npm run test:all`)
- [x] Extended the README / documentation, if necessary

^^^ I am on such a bad connection right now, that I can't even do `npm install` correctly. I need someone to check, review and enhance if needed. I've never worked with mocha before, so also please check the test I added. Maybe it would also be good to add a test that checks what happens if `.tldrrc` file is missing.

Patch:
diff --git a/README.md b/README.md
index d171de4..90d210d 100644
--- a/README.md
+++ b/README.md
@@ -98,7 +98,16 @@ As a contributor, you can also point to your own fork containing the `tldr.zip`
 
 ```js
 {
-  "repository" : "http://myrepo/assets/tldr.zip",
+  "repository": "http://myrepo/assets/tldr.zip"
+}
+```
+
+By default, a cache update is performed anytime a page is not found for a command. To prevent this behavior,
+you can set the configuration variable `skipUpdateWhenPageNotFound` to `true` (defaults to `false`):
+
+```js
+{
+  "skipUpdateWhenPageNotFound": true
 }
 ```
 
diff --git a/config.json b/config.json
index 581931b..5342d90 100644
--- a/config.json
+++ b/config.json
@@ -1,6 +1,7 @@
 {
   "pagesRepository": "https://github.com/tldr-pages/tldr",
   "repository": "https://tldr.sh/assets/tldr.zip",
+  "skipUpdateWhenPageNotFound": false,
   "themes": {
     "simple": {
       "commandName": "bold, underline",
diff --git a/lib/config.js b/lib/config.js
index 6d206fa..04b5941 100644
--- a/lib/config.js
+++ b/lib/config.js
@@ -16,8 +16,9 @@ exports.get = () => {
   try {
     customConfig = JSON.parse(fs.readFileSync(CUSTOM));
   } catch (ex) {
-    /*eslint-disable */
-    /*eslint-enable */
+    if (ex instanceof SyntaxError) {
+      throw new Error('The content of .tldrrc is not a valid JSON object:\n' + ex);
+    }
   }
 
   let merged = defaults(customConfig, defaultConfig);
diff --git a/lib/tldr.js b/lib/tldr.js
index 823e0fc..27b1adb 100644
--- a/lib/tldr.js
+++ b/lib/tldr.js
@@ -129,7 +129,10 @@ class Tldr {
       .then((content) => {
         // If found in first try, render it
         if (!content) {
-          // If not found, try to update
+          // If not found, try to update cache unless user explicitly wants to skip
+          if (this.config.skipUpdateWhenPageNotFound === true) {
+            return '';
+          }
           return spinningPromise('Page not found. Updating cache...', () => {
             return this.cache.update();
           })


Test patch:
diff --git a/test/config.spec.js b/test/config.spec.js
index 3ab2ab2..7f4d430 100644
--- a/test/config.spec.js
+++ b/test/config.spec.js
@@ -18,7 +18,11 @@ describe('Config', () => {
   "repository": "http://myrepo/assets/tldr.zip"
 }`;
 
-  const CUSTOM_INVALID =
+  const CUSTOM_INVALID_JSON =
+`# comments are not allowed in json
+{}`;
+
+  const CUSTOM_INVALID_SCHEMA =
 `
 {
   "themes": {
@@ -53,9 +57,15 @@ describe('Config', () => {
     config.get().repository.should.eql('http://myrepo/assets/tldr.zip');
   });
 
-  it('should validate the custom config format', () => {
+  it('should validate the custom config JSON', () => {
+    fs.readFileSync.onCall(0).returns(DEFAULT);
+    fs.readFileSync.onCall(1).returns(CUSTOM_INVALID_JSON);
+    config.get.should.throw(/not a valid JSON object/);
+  });
+
+  it('should validate the custom config schema', () => {
     fs.readFileSync.onCall(0).returns(DEFAULT);
-    fs.readFileSync.onCall(1).returns(CUSTOM_INVALID);
+    fs.readFileSync.onCall(1).returns(CUSTOM_INVALID_SCHEMA);
     config.get.should.throw(/Invalid theme value/);
   });