rescript-schema icon indicating copy to clipboard operation
rescript-schema copied to clipboard

parseOrThrow error very noisy on TS

Open chenglou opened this issue 10 months ago • 8 comments

Hey @DZakh! Nice library

import * as S from 'rescript-schema'

const payload = S.object(() => ({
  a: S.optional(S.string),
}))

S.parseOrThrow(1, payload)

This generates 7 blocks of error with TS, totally >150 lines 😅

chenglou avatar Feb 22 '25 03:02 chenglou

Hm, I see only Failed parsing at root. Reason: Expected {}, received 1 in runtime. I don't really understand what you mean by 7 blocks of error.

But in this case the payload schema has the type:

const payload: S.Schema<{
    a: S.Schema<string | undefined, string | undefined>;
}, Record<string, unknown>>

This is because when you use s.object you need to wrap the schema with s.field like:

const payload = S.object((s) => ({
  a: s.field("a", S.optional(S.string)),
}));

S.parseOrThrow(1, payload);
//? Failed parsing at root. Reason: Expected { a: string | undefined; }, received 1

Or you can use a shorter version with S.schema:

const payload = S.schema({
  a: S.optional(S.string),
});

S.parseOrThrow(1, payload);
//? Failed parsing at root. Reason: Expected { a: string | undefined; }, received 1

DZakh avatar Feb 22 '25 06:02 DZakh

But I'll think about how to prevent the case of forgetting to use s.field inside of S.object 🫡

DZakh avatar Feb 22 '25 06:02 DZakh

Ah to clarify, I knew about this error and should have given a simpler repro. That's orthogonal to the issue, sorry for the confusion.

So I'm logging the error object itself, not the message. In node:

/github/test/node_modules/rescript-schema/src/S_Core.res.js:408
  throw new RescriptSchemaError(code, b.g.o, path);
  ^

<ref *1> RescriptSchemaError: Failed parsing at root. Reason: Expected {}, received 1
    at raise (/github/test/node_modules/rescript-schema/src/S_Core.res.js:408:9)
    at Array.<anonymous> (/github/test/node_modules/rescript-schema/src/S_Core.res.js:434:26)
    at eval (eval at compile (/github/test/node_modules/rescript-schema/src/S_Core.res.js:593:10), <anonymous>:3:45)
    at Object.parseOrThrow (/github/test/node_modules/rescript-schema/src/S_Core.res.js:893:32)
    at Object.<anonymous> (/github/test/src/hey.ts:7:3)
    at Module._compile (node:internal/modules/cjs/loader:1566:14)
    at Object..js (node:internal/modules/cjs/loader:1718:10)
    at Module.load (node:internal/modules/cjs/loader:1305:32)
    at Function._load (node:internal/modules/cjs/loader:1119:12)
    at TracingChannel.traceSync (node:diagnostics_channel:322:14) {
  flag: 1,
  code: {
    TAG: 'InvalidType',
    expected: {
      '1': [Function (anonymous)],
      t: {
        TAG: 'object',
        items: [],
        fields: {},
        unknownKeys: 'Strip',
        advanced: true
      },
      n: [Function: name$2],
      '~r': [Function (anonymous)],
      b: [Function (anonymous)],
      f: [Function: typeFilter$1],
      i: false,
      m: {}
    },
    received: 1
  },
  path: '',
  s: Symbol(rescript-schema),
  RE_EXN_ID: 'S_Core-RescriptSchema.Raised',
  _1: [Circular *1],
  Error: [Circular *1]
}

In Bun:

167 |   n: false
168 | };
169 | 
170 | class RescriptSchemaError extends Error {
171 |       constructor(code, flag, path) {
172 |         super();
              ^
RescriptSchemaError: Failed parsing at root. Reason: Expected {}, received 1
      flag: 1,
      code: {
  TAG: "InvalidType",
  expected: [Object ...],
  received: 1,
},
      path: "",
         s: Symbol(rescript-schema),
 RE_EXN_ID: "S_Core-RescriptSchema.Raised",

      at new RescriptSchemaError (github/test/node_modules/rescript-schema/src/S_Core.res.js:172:9)
      at raise (github/test/node_modules/rescript-schema/src/S_Core.res.js:408:9)
      at <anonymous> (file://github/test/node_modules/rescript-schema/src/S_Core.res.js:3:45)
      at <anonymous> (github/test/src/hey.ts:7:3)

167 |   n: false
168 | };
169 | 
170 | class RescriptSchemaError extends Error {
171 |       constructor(code, flag, path) {
172 |         super();
              ^
RescriptSchemaError: Failed parsing at root. Reason: Expected {}, received 1
      flag: 1,
      code: {
  TAG: "InvalidType",
  expected: [Object ...],
  received: 1,
},
      path: "",
         s: Symbol(rescript-schema),
 RE_EXN_ID: "S_Core-RescriptSchema.Raised",
        _1: 167 |   n: false
168 | };
169 | 
170 | class RescriptSchemaError extends Error {
171 |       constructor(code, flag, path) {
172 |         super();
              ^
RescriptSchemaError: Failed parsing at root. Reason: Expected {}, received 1
      flag: 1,
      code: [Object ...],
      path: "",
         s: Symbol(rescript-schema),
 RE_EXN_ID: "S_Core-RescriptSchema.Raised",
        _1: [Circular],
     Error: [Circular],

      at new RescriptSchemaError (github/test/node_modules/rescript-schema/src/S_Core.res.js:172:9)
      at raise (github/test/node_modules/rescript-schema/src/S_Core.res.js:408:9)
      at <anonymous> (file://github/test/node_modules/rescript-schema/src/S_Core.res.js:3:45)
      at <anonymous> (github/test/src/hey.ts:7:3)
,
     Error: 167 |   n: false
168 | };
169 | 
170 | class RescriptSchemaError extends Error {
171 |       constructor(code, flag, path) {
172 |         super();
              ^
RescriptSchemaError: Failed parsing at root. Reason: Expected {}, received 1
      flag: 1,
      code: [Object ...],
      path: "",
         s: Symbol(rescript-schema),
 RE_EXN_ID: "S_Core-RescriptSchema.Raised",
        _1: [Circular],
     Error: [Circular],

      at new RescriptSchemaError (github/test/node_modules/rescript-schema/src/S_Core.res.js:172:9)
      at raise (github/test/node_modules/rescript-schema/src/S_Core.res.js:408:9)
      at <anonymous> (file://github/test/node_modules/rescript-schema/src/S_Core.res.js:3:45)
      at <anonymous> (github/test/src/hey.ts:7:3)
,

      at new RescriptSchemaError (github/test/node_modules/rescript-schema/src/S_Core.res.js:172:9)
      at raise (github/test/node_modules/rescript-schema/src/S_Core.res.js:408:9)
      at <anonymous> (file://github/test/node_modules/rescript-schema/src/S_Core.res.js:3:45)
      at <anonymous> (github/test/src/hey.ts:7:3)

167 |   n: false
168 | };
169 | 
170 | class RescriptSchemaError extends Error {
171 |       constructor(code, flag, path) {
172 |         super();
              ^
RescriptSchemaError: Failed parsing at root. Reason: Expected {}, received 1
      flag: 1,
      code: {
  TAG: "InvalidType",
  expected: [Object ...],
  received: 1,
},
      path: "",
         s: Symbol(rescript-schema),
 RE_EXN_ID: "S_Core-RescriptSchema.Raised",
        _1: 167 |   n: false
168 | };
169 | 
170 | class RescriptSchemaError extends Error {
171 |       constructor(code, flag, path) {
172 |         super();
              ^
RescriptSchemaError: Failed parsing at root. Reason: Expected {}, received 1
      flag: 1,
      code: [Object ...],
      path: "",
         s: Symbol(rescript-schema),
 RE_EXN_ID: "S_Core-RescriptSchema.Raised",
        _1: [Circular],
     Error: [Circular],

      at new RescriptSchemaError (github/test/node_modules/rescript-schema/src/S_Core.res.js:172:9)
      at raise (github/test/node_modules/rescript-schema/src/S_Core.res.js:408:9)
      at <anonymous> (file://github/test/node_modules/rescript-schema/src/S_Core.res.js:3:45)
      at <anonymous> (github/test/src/hey.ts:7:3)
,
     Error: 167 |   n: false
168 | };
169 | 
170 | class RescriptSchemaError extends Error {
171 |       constructor(code, flag, path) {
172 |         super();
              ^
RescriptSchemaError: Failed parsing at root. Reason: Expected {}, received 1
      flag: 1,
      code: [Object ...],
      path: "",
         s: Symbol(rescript-schema),
 RE_EXN_ID: "S_Core-RescriptSchema.Raised",
        _1: [Circular],
     Error: [Circular],

      at new RescriptSchemaError (github/test/node_modules/rescript-schema/src/S_Core.res.js:172:9)
      at raise (github/test/node_modules/rescript-schema/src/S_Core.res.js:408:9)
      at <anonymous> (file://github/test/node_modules/rescript-schema/src/S_Core.res.js:3:45)
      at <anonymous> (github/test/src/hey.ts:7:3)
,

      at new RescriptSchemaError (github/test/node_modules/rescript-schema/src/S_Core.res.js:172:9)
      at raise (github/test/node_modules/rescript-schema/src/S_Core.res.js:408:9)
      at <anonymous> (file://github/test/node_modules/rescript-schema/src/S_Core.res.js:3:45)
      at <anonymous> (github/test/src/hey.ts:7:3)

chenglou avatar Feb 22 '25 06:02 chenglou

Wow, Bun looks completely broken 😱 I don't know how to fix it, but I'll try. Also, I plan to make the schema object cleaner in the V10, so expected should look much better in Node.js

DZakh avatar Feb 22 '25 06:02 DZakh

Thanks for letting me know 🫡

DZakh avatar Feb 22 '25 06:02 DZakh

cc @Jarred-Sumner if I'm not mistaken, this might be on Bun's side for console printing heuristics

chenglou avatar Feb 22 '25 06:02 chenglou

oh, I wonder if we're calling getters somewhere

Jarred-Sumner avatar Feb 22 '25 06:02 Jarred-Sumner

Message is a getter here https://github.com/DZakh/rescript-schema/blob/92f8e75d3e3003054c30e422da750fdc3b0abbe1/src/S_Core.res#L401-L403

DZakh avatar Feb 22 '25 07:02 DZakh

@chenglou Improved the error display in the commit https://github.com/DZakh/rescript-schema/pull/109/commits/1847b9c8ee727bb9cd3dd47b958c179f1ab32b7c . Gradually getting closer to the release 🏗️

DZakh avatar Apr 04 '25 16:04 DZakh

Image

DZakh avatar Apr 04 '25 16:04 DZakh

Still some work to clean up the schema and error codes.

DZakh avatar Apr 04 '25 16:04 DZakh

Improved a lot in v10. Please reopen if it's still an issue 👍

DZakh avatar May 03 '25 19:05 DZakh