@stonyx/logs 1.0.1-alpha.22 → 1.0.1-alpha.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +21 -8
  2. package/dist/index.js +12 -4
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -153,21 +153,27 @@ These methods can then be called in your application with [logging parameters](#
153
153
 
154
154
  Color settings are handled by determining whether your input is a color name or a hex value (prefixed with **#**). For example, passing `red` as a color setting will utilize `chalk.red`, while passing `#ff0000` would use `chalk.hex('#ff0000')` instead. A [list of available colors](https://github.com/chalk/chalk#colors) can be found in chalks' documentation.
155
155
 
156
- Additionally, these methods return a promise when `logToFile` is true, allowing you use them with `await` in an async method, or append `then(), catch(), or finally()` for more advanced callback usage.
156
+ Additionally, these methods return a promise when `logToFile` is true. That promise rejecting is the only signal that a write failed, so you must either `await` the call or attach a `.catch()` — see [File Write Failures](#file-write-failures). `then()` and `finally()` are also available.
157
157
 
158
158
  ```js
159
159
  async method() {
160
- await log.error('error message', true);
160
+ try {
161
+ await log.error('error message', true);
161
162
 
162
- // do something after logs/error.log (default) is created
163
+ // do something after logs/error.log (default) is created
164
+ } catch (err) {
165
+ // the write failed; the rejection is the only notice you get
166
+ process.stderr.write(`log write failed: ${err.code}\n`);
167
+ }
163
168
  }
164
169
  ```
165
170
 
166
171
  #### File Write Failures
167
172
 
168
- When `logToFile` is true, **the returned promise rejecting is the only failure signal.** Nothing is
169
- printed and no fallback log is written when the log directory or file cannot be written: the
170
- underlying `fs` error is propagated to the caller with its `code` intact (`EACCES`, `EPERM`,
173
+ When `logToFile` is true, **the returned promise rejecting is the only failure signal.** The log
174
+ line itself is still written to the console as usual, but **no error notice is printed** and no
175
+ fallback log is written when the log directory or file cannot be written: the underlying `fs` error
176
+ is propagated to the caller with its `code` intact (`ENOENT`, `ENOTDIR`, `EACCES`, `EPERM`,
171
177
  `EROFS`, ...).
172
178
 
173
179
  A fire-and-forget call therefore produces an **unhandled promise rejection** on a failed write.
@@ -181,8 +187,15 @@ log.error('error message', true);
181
187
  log.error('error message', true).catch(err => process.stderr.write(`log write failed: ${err.code}\n`));
182
188
  ```
183
189
 
184
- A write that fails because the log directory was removed at runtime is retried once against a
185
- freshly created directory before the rejection surfaces.
190
+ A failed write is retried exactly once, and only for the two codes that recreating the log directory
191
+ can repair: `ENOENT` (the directory was removed at runtime) and `ENOTDIR` (a path component was
192
+ replaced by a non-directory). The directory cache entry is dropped, the directory is recreated, and
193
+ the write is reattempted once before the rejection surfaces. If the recreate itself fails, that
194
+ error is what surfaces.
195
+
196
+ Every other code — including `EACCES`, `EPERM` and `EROFS` — rejects immediately with no retry,
197
+ because `mkdir` on an existing directory is a successful no-op: it cannot change a permission bit or
198
+ a read-only mount, so a retry could only ever repeat the same failure at twice the syscall cost.
186
199
 
187
200
  ### The Debug Method
188
201
 
package/dist/index.js CHANGED
@@ -20,10 +20,18 @@ const defaultOptions = {
20
20
  // used to sanitize defineType() options input
21
21
  const optionKeys = Object.keys(defaultOptions);
22
22
  /*
23
- * Write failures where the cached log directory may have been removed or made
24
- * unavailable at runtime. These invalidate the directory cache and are retried once.
23
+ * Write failures that a recursive mkdir of the log directory can actually repair:
24
+ * ENOENT (the cached directory was removed at runtime) and ENOTDIR (a path component
25
+ * was replaced by a non-directory). These invalidate the directory cache and are
26
+ * retried once.
27
+ *
28
+ * Permission and mount faults (EACCES, EPERM, EROFS) are deliberately excluded: the
29
+ * retry's only remediation is mkdir(recursive), which is a successful no-op on an
30
+ * existing directory and can change neither a mode nor a mount flag. Retrying them
31
+ * doubled the syscalls on a permanently failing write and defeated the
32
+ * one-mkdir-per-directory invariant this cache exists to establish.
25
33
  */
26
- const recoverableWriteCodes = new Set(['ENOENT', 'EACCES', 'EPERM', 'EROFS']);
34
+ const recoverableWriteCodes = new Set(['ENOENT', 'ENOTDIR']);
27
35
  export default class Log {
28
36
  options;
29
37
  color;
@@ -138,7 +146,7 @@ export default class Log {
138
146
  }
139
147
  catch (error) {
140
148
  const { code } = error;
141
- if (!code || !recoverableWriteCodes.has(code))
149
+ if (!recoverableWriteCodes.has(code))
142
150
  throw error;
143
151
  /*
144
152
  * The cached directory may have been removed underneath a warm cache. Invalidate
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stonyx/logs",
3
- "version": "1.0.1-alpha.22",
3
+ "version": "1.0.1-alpha.24",
4
4
  "description": "Simplified logging for node applications",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",