fix(mocks): separate a body read failure from a missing showmeta floor
Three review follow-ups on the guard the sas9 tree loads. - A body that cannot be read is now its own error, naming the path and the filesystem message. Reporting it as missing metadata sent the reader to a @sasjs/utils reinstall that cannot fix a path. - One statement of the dependency fact: showmeta arrived in @sasjs/utils 4.6.0 and @sasjs/server declares that floor from 3.12.3 (3.12.0 and 3.12.2 declare ^4.4.0, checked with npm view), so the message names the server version to install instead of "reinstall the server". - CONTRIBUTING lists _program and weboutPath among the predeclared globals, which the guarded services use to locate the helper. The sasjs tree's copy in dcMockUtils.js had the same two defects, so both now say one thing rather than one tree being clearer than the other.
This commit is contained in:
1 parent
7be3f84073
commit
744c89b919
3 files changed
+46
-19
No files matched your search
+1
-1
@@ -147,7 +147,7 @@ The app will be at `http://localhost:4200`. It calls the JS mock services on por
|
||||
|
||||
### How the mocks work
|
||||
|
||||
Each `.js` file in `sas/mocks/sasjs/services/` corresponds to a real SAS service (e.g. `public/startupservice.js` mimics `services/public/startupservice.sas`). The JS runtime predeclares `fs` and `_webout`, and the services emit their members through the runtime's `webout()` - `webout('OPEN')`, one `webout('OBJ', name, rows)` (or `webout('ARR', name, rows)` for positional rows) per member, `webout('CLOSE')` - so the response envelope comes from the host and the file carries only what the SAS service returns. A few services still write the body themselves through `_webout`: the ones that emit plain text, CSV, DDL or HTML and set their own content headers (`admin/exportdb`, `admin/makedata`, `public/getrawdata`, `public/getddl`), and the lineage captures. Some mocks are stateful: they persist data to a `mock-storage/` folder on the SASjs Drive (e.g. `licence.json`, `users.json`, `filter.txt`) using the predeclared `fs` module.
|
||||
Each `.js` file in `sas/mocks/sasjs/services/` corresponds to a real SAS service (e.g. `public/startupservice.js` mimics `services/public/startupservice.sas`). The JS runtime predeclares `fs`, `_program` (the program's deployed path), `weboutPath` (the response body it writes) and `_webout`, and the services emit their members through the runtime's `webout()` - `webout('OPEN')`, one `webout('OBJ', name, rows)` (or `webout('ARR', name, rows)` for positional rows) per member, `webout('CLOSE')` - so the response envelope comes from the host and the file carries only what the SAS service returns. A few services still write the body themselves through `_webout`: the ones that emit plain text, CSV, DDL or HTML and set their own content headers (`admin/exportdb`, `admin/makedata`, `public/getrawdata`, `public/getddl`), and the lineage captures. Some mocks are stateful: they persist data to a `mock-storage/` folder on the SASjs Drive (e.g. `licence.json`, `users.json`, `filter.txt`) using the predeclared `fs` module.
|
||||
|
||||
The mock data includes sample tables (`DC996664.MPE_X_TEST`, `MPE_X_NEW`, `MPE_X_FORMULA_TEST`, etc.) with realistic columns, validation rules (HARDREGEX, SOFTREGEX, HARDSELECT, READONLY, HIDDEN, ROUND, NUMBER_FORMAT), and dropdown values. This is sufficient to exercise the full editor grid, approval workflow, viewer, and admin screens.
|
||||
|
||||
|
||||
@@ -14,21 +14,35 @@
|
||||
* SYSCC 0 while the metadata is missing, which is the failure this prevents.
|
||||
*
|
||||
* `showmeta` arrived in @sasjs/utils 4.6.0, and @sasjs/server only declares
|
||||
* `^4.6.0` from 3.12.3 - an older pinned server accepts the fourth argument and
|
||||
* ignores it, writing the rows and dropping the metadata without a word.
|
||||
* Reading the output is how that becomes visible; an arity check
|
||||
* (`webout.length`) stops counting at the first default parameter, so a runtime
|
||||
* that does carry the option can report three and be refused wrongly.
|
||||
* that floor from 3.12.3 (3.12.0 and 3.12.2 declare `^4.4.0`) - an older pinned
|
||||
* server accepts the fourth argument and ignores it, writing the rows and
|
||||
* dropping the metadata without a word. Reading the output is how that becomes
|
||||
* visible; an arity check (`webout.length`) stops counting at the first default
|
||||
* parameter, so a runtime that does carry the option can report three and be
|
||||
* refused wrongly.
|
||||
*
|
||||
* @param {string} bodyPath the response body the program is writing
|
||||
* @param {string} member the member the caller wrote
|
||||
*/
|
||||
function requireMemberMetadata(bodyPath, member) {
|
||||
let body = ''
|
||||
let body
|
||||
try {
|
||||
body = fs.readFileSync(bodyPath, 'utf8')
|
||||
} catch (err) {
|
||||
body = ''
|
||||
// A body that cannot be read is a path or filesystem problem, and reporting
|
||||
// it as missing metadata would send the reader to a dependency reinstall
|
||||
// that cannot fix it.
|
||||
throw new Error(
|
||||
"webout() could not read the response body at '" +
|
||||
bodyPath +
|
||||
"' (" +
|
||||
(err && err.message ? err.message : err) +
|
||||
"), so the column metadata for '" +
|
||||
member +
|
||||
"' cannot be checked. This is a path or filesystem problem, not a " +
|
||||
'@sasjs/utils version problem - check the weboutPath of the program ' +
|
||||
'that called it.'
|
||||
)
|
||||
}
|
||||
|
||||
if (body.indexOf('"$' + String(member).toLowerCase() + '"') >= 0) return
|
||||
@@ -37,8 +51,9 @@ function requireMemberMetadata(bodyPath, member) {
|
||||
"webout() did not emit the column metadata for '" +
|
||||
member +
|
||||
"', so the response would carry rows without their formats and labels. " +
|
||||
'The options argument arrived in @sasjs/utils 4.6.0; @sasjs/server 3.12 ' +
|
||||
'declares ^4.4.0 and can resolve 4.5.x. Reinstall the server, or upgrade ' +
|
||||
'@sasjs/utils to 4.6.0 or later.'
|
||||
'The options argument arrived in @sasjs/utils 4.6.0, and @sasjs/server ' +
|
||||
'declares that floor from 3.12.3 - an older server accepts it and drops ' +
|
||||
'it. Install @sasjs/server 3.12.3 or later, or @sasjs/utils 4.6.0 or ' +
|
||||
'later, on the host running this program.'
|
||||
)
|
||||
}
|
||||
@@ -43,9 +43,11 @@ const MONTHS_NUM = {JAN:'01',FEB:'02',MAR:'03',APR:'04',MAY:'05',JUN:'06',JUL:'0
|
||||
* exists to prevent. Before CLOSE the body cannot be closed, so the run fails.
|
||||
*
|
||||
* A runtime without the option - an `@sasjs/utils` below 4.6.0, which
|
||||
* `@sasjs/server`'s `^4.4.0` range can resolve - writes the rows and drops the
|
||||
* metadata silently. The response still looks complete, so the estate quietly
|
||||
* tests less than it claims. Refuse it instead, and name the cause.
|
||||
* `@sasjs/server`'s `^4.4.0` range can resolve on releases before 3.12.3 -
|
||||
* writes the rows and drops the metadata silently. The response still looks
|
||||
* complete, so the estate quietly tests less than it claims. Refuse it instead,
|
||||
* and name the cause. The sas9 tree carries the same function in
|
||||
* `sas/mocks/sas9/sasjs/services/weboutGuard.js`; keep the two saying one thing.
|
||||
*
|
||||
* Testing the output rather than the function is deliberate: an arity check
|
||||
* (`webout.length`) stops counting at the first default or rest parameter, so a
|
||||
@@ -55,11 +57,20 @@ const MONTHS_NUM = {JAN:'01',FEB:'02',MAR:'03',APR:'04',MAY:'05',JUN:'06',JUL:'0
|
||||
* @param {string} member the member the caller wrote
|
||||
*/
|
||||
function requireMemberMetadata(bodyPath, member) {
|
||||
let body = ''
|
||||
let body
|
||||
try {
|
||||
body = fs.readFileSync(bodyPath, 'utf8')
|
||||
} catch (err) {
|
||||
body = ''
|
||||
// A body that cannot be read is a path or filesystem problem, and
|
||||
// reporting it as missing metadata would send the reader to a
|
||||
// dependency reinstall that cannot fix it.
|
||||
throw new Error(
|
||||
"webout() could not read the response body at '" + bodyPath + "' (" +
|
||||
(err && err.message ? err.message : err) + "), so the column " +
|
||||
"metadata for '" + member + "' cannot be checked. This is a " +
|
||||
'path or filesystem problem, not a @sasjs/utils version ' +
|
||||
'problem - check the weboutPath of the program that called it.'
|
||||
)
|
||||
}
|
||||
|
||||
if (body.indexOf('"$' + String(member).toLowerCase() + '"') >= 0) return
|
||||
@@ -67,9 +78,10 @@ function requireMemberMetadata(bodyPath, member) {
|
||||
throw new Error(
|
||||
"webout() did not emit the column metadata for '" + member + "', so the " +
|
||||
'response would carry rows without their formats and labels. The ' +
|
||||
'options argument arrived in @sasjs/utils 4.6.0; @sasjs/server 3.12 ' +
|
||||
'declares ^4.4.0 and can resolve 4.5.x. Reinstall the server, or ' +
|
||||
'upgrade @sasjs/utils to 4.6.0 or later.'
|
||||
'options argument arrived in @sasjs/utils 4.6.0, and @sasjs/server ' +
|
||||
'declares that floor from 3.12.3 - an older server accepts it and ' +
|
||||
'drops it. Install @sasjs/server 3.12.3 or later, or @sasjs/utils ' +
|
||||
'4.6.0 or later, on the host running this program.'
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user