Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error: Internal error: Defined value expected, but got undefined. #1629

Open
noppej opened this issue Jan 14, 2021 · 9 comments
Open

Error: Internal error: Defined value expected, but got undefined. #1629

noppej opened this issue Jan 14, 2021 · 9 comments

Comments

@noppej
Copy link

noppej commented Jan 14, 2021

The quicktype CLI fails with the above error, when executing the following
quicktype --lang rs --derive-debug --density dense --visibility private --out debugProtocolTypes.rs --src-lang typescript --src-urls https://raw.githubusercontent.com/microsoft/vscode/master/src/vs/workbench/contrib/debug/common/debugProtocol.d.ts

The same input file and options on quicktype.io produces code successfully.

@mindplay-dk
Copy link

mindplay-dk commented Jan 18, 2022

I don't think this is related to --src-lang typescript - I am getting the same error with --src-lang schema:

$ npx quicktype -- --src-lang schema --lang cs schema.json
Error: Internal error: Defined value expected, but got undefined.

As someone pointed out in #1062, this error message isn't really helpful.

Here is my schema I'm using the Pokedex schema from the example on the website, verbatim:

schema.json
{
  "$ref": "#/definitions/Pokedex",
  "definitions": {
    "Pokedex": {
      "type": "object",
      "additionalProperties": false,
      "description": "A collection of pokémon",
      "properties": {
        "pokemon": {
          "type": "array",
          "description": "All pokémon contained in the pokédex",
          "items": {
            "$ref": "#/definitions/Pokemon"
          }
        }
      },
      "required": [
        "pokemon"
      ],
      "title": "Pokedex"
    },
    "Pokemon": {
      "type": "object",
      "additionalProperties": false,
      "description": "A 'pocket monster.' One must catch them all.",
      "properties": {
        "id": {
          "description": "A unique identifier for this pokémon.\nHigher ids generally imply rarer and more evolved pokémon.",
          "type": "integer"
        },
        "num": {
          "type": "string"
        },
        "name": {
          "type": "string"
        },
        "img": {
          "description": "Photographic evidence of this pokémon's existence",
          "type": "string"
        },
        "type": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/Type"
          }
        },
        "height": {
          "type": "string"
        },
        "weight": {
          "type": "string"
        },
        "candy": {
          "description": "The flavor of candy preferred by this pokémon",
          "type": "string"
        },
        "candy_count": {
          "type": "integer"
        },
        "egg": {
          "type": "string",
          "enum": [
            "2 km",
            "Not in Eggs",
            "5 km",
            "10 km",
            "Omanyte Candy"
          ],
          "title": "egg"
        },
        "spawn_chance": {
          "type": "number"
        },
        "avg_spawns": {
          "type": "number"
        },
        "spawn_time": {
          "type": "string"
        },
        "multipliers": {
          "oneOf": [
            {
              "type": "array",
              "items": {
                "type": "number"
              }
            },
            {
              "type": "null"
            }
          ],
          "title": "multipliers"
        },
        "weaknesses": {
          "type": "array",
          "description": "Types of pokémon that cause extra damage to this pokémon",
          "items": {
            "$ref": "#/definitions/Type"
          }
        },
        "next_evolution": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/Evolution"
          }
        },
        "prev_evolution": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/Evolution"
          }
        }
      },
      "required": [
        "avg_spawns",
        "candy",
        "egg",
        "height",
        "id",
        "img",
        "multipliers",
        "name",
        "num",
        "spawn_chance",
        "spawn_time",
        "type",
        "weaknesses",
        "weight"
      ],
      "title": "pokemon"
    },
    "Type": {
      "type": "string",
      "enum": [
        "Fire",
        "Ice",
        "Flying",
        "Psychic",
        "Water",
        "Ground",
        "Rock",
        "Electric",
        "Grass",
        "Fighting",
        "Poison",
        "Bug",
        "Fairy",
        "Ghost",
        "Dark",
        "Steel",
        "Dragon"
      ],
      "title": "type"
    },
    "Evolution": {
      "type": "object",
      "additionalProperties": false,
      "description": "A description of an evolutionary stage of a pokémon",
      "properties": {
        "num": {
          "description": "The number of the pokémon to or from which the containing pokémon evolves",
          "type": "string"
        },
        "name": {
          "description": "The name of the Pokémon to or from which the containing Pokémon evolves",
          "type": "string"
        }
      },
      "required": [
        "name",
        "num"
      ],
      "title": "_evolution"
    }
  }
}

This schema passes validation on jsonschemavalidator.net - and yes, the same input on quicktype.io produces code successfully, so I am at a loss here - without an error message explaining what quicktype thinks is wrong with this (and where) there doesn't seem to be much more I can do to debug this.

@mindplay-dk
Copy link

So here's why we're not getting a helpful error message: (#1062)

https://github.com/quicktype/quicktype/blob/29f459dc95fe887d9e03cc19d65bc9908364b11a/src/quicktype-core/support/Support.ts#L52-L55

Even if I change this into throw new Error("Defined value expected, but got undefined");, the CLI appears to catch and silence any error details, also not helpful:

https://github.com/quicktype/quicktype/blob/29f459dc95fe887d9e03cc19d65bc9908364b11a/src/cli/index.ts#L989-L998

Replacing the body of that error-handling callback with throw e, I get a stack-trace:

UnhandledPromiseRejectionWarning: Error: Defined value expected, but got undefined
    at Object.defined (/home/mindplay/workspace/Muninn/components/tracker/node_modules/quicktype/dist/quicktype-core/support/Support.js:49:11)
    at Ref.get address [as address] (/home/mindplay/workspace/Muninn/components/tracker/node_modules/quicktype/dist/quicktype-core/input/JSONSchemaInput.js:136:26)
    at Resolver.<anonymous> (/home/mindplay/workspace/Muninn/components/tracker/node_modules/quicktype/dist/quicktype-core/input/JSONSchemaInput.js:502:54)
    at Generator.next (<anonymous>)
    at fulfilled (/home/mindplay/workspace/Muninn/components/tracker/node_modules/quicktype/dist/quicktype-core/input/JSONSchemaInput.js:4:58)

@noppej could you try the same hack to see if your stack-trace is coming from the same location? (just edit the corresponding .js files in your node_modules folder - and reinstall it when you're done.)

(as for fixing #1062, I would suggest catching only a specific, internal class CommandError or something - make that the only type of error you handle in the CLI in this way, so that other errors, don't get silenced... e.g. don't silence errors unless you're sure the error message is "expected" and "user-friendly" enough that it makes sense to bypass standard error-handling... errors generated using panic, in particular, most likely should not be silenced, as they are "unexpected".)

@mindplay-dk
Copy link

For the record, I've tested at least two dozen older versions - it doesn't look like this ever worked.

I went back to releases as old as 5 years.

How is it the website has a working version, and no version in the npm registry ever worked?

Could this be a problem with the CLI front-end itself? (Is the website using the latest version?)

@mindplay-dk
Copy link

The problem is here, I think:

https://github.com/quicktype/quicktype/blob/daffe53101c4d329c0647fb8310aded585e3808e/src/quicktype-core/input/JSONSchemaInput.ts#L188-L190

However, the call to that function is coming from a line that is itself trying to generate an error-message, here:

https://github.com/quicktype/quicktype/blob/daffe53101c4d329c0647fb8310aded585e3808e/src/quicktype-core/input/JSONSchemaInput.ts#L608

So this obscured error-message is preventing the actual error-message from being generated.

It looks like the intention is for address to be checked for presence with hasAddress prior to calling it, so I changed it to:

return schemaFetchError(base, virtualRef.hasAddress ? virtualRef.address : "<missing address>");

So now we can at least see the intended error-message:

UnhandledPromiseRejectionWarning: Error: Could not fetch schema <missing address>, referred to from --#

I'm unable to go further with this at the moment, but hopefully this is helpful to the maintainers...

@mindplay-dk
Copy link

As to why this works on the website, the constructor looks like a good lead:

https://github.com/quicktype/quicktype/blob/daffe53101c4d329c0647fb8310aded585e3808e/src/quicktype-core/input/JSONSchemaInput.ts#L175-L182

My guess is, the website never leaves the addressURI constructor argument as undefined.

@mindplay-dk
Copy link

...problem solved. 😅

There was nothing specifically wrong with my schema - even the simple "coordinate" sample from the site wouldn't work.

Why?

This 👎

./node_modules/.bin/quicktype -- --src-lang schema --lang cs --namespace CookiebotTracker schema.json

Versus this 👍

./node_modules/.bin/quicktype --src-lang schema --lang cs --namespace CookiebotTracker schema.json

Apparently the CLI argument parser takes -- to be the input filename. 🤦‍♂️

So it looks like I just spent an entire day debugging this because of missing input validation and/or misleading error-reporting.

Welp. Looks like it's back to #1062 for this one.

@robogeek
Copy link

FWYW -- Looking for clues on resolving the same error message (as said above, this message is unhelpful), I landed on this page.

In my case, the issue was the input file name was incorrect.

But, as noted above, the actual error message is hidden leaving the users with no guidance.

@kriswest
Copy link
Contributor

I've spent the last couple of days hunting for errors in my schemas and hit the same as @robogeek. It would make sense to validate that the input files exist in the CLI and give a more meaningful message that this obtuse one later on in the process.

This is one of several obtuse messages that are hard to track back to the source of the issue - but this seems easy enough to improve on compared to some of the others (e.g. 'Error: Value of type string is not valid JSON Schema' which can have a variety of causes). I think input validation is worth doing as when enabling --debug all you'll have real trouble determining which schema, file or issue is the cause.

@tgrushka
Copy link

Quicktype fails on almost any non-trivial TypeScript file I throw at it trying to convert to Rust.

A trivial file such as the following works:

interface RunOptions {
    absolutePaths: boolean
    ancestry: boolean
    iframes: boolean
    xpath: boolean
}
quicktype --lang rs --derive-debug --density dense --src-lang typescript --src axe-types.ts
...
use serde::{Serialize, Deserialize};

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct RunOptions {
    absolute_paths: bool,
    ancestry: bool,
    iframes: bool,
    xpath: bool,
}

It won't run at all on axe.d.ts. But even when I re-export a specific type in a wrapper file, with nothing else in the file:

export { RunOptions } from 'axe-core'

from axe.d.ts:

declare namespace axe {
...
  interface RunOptions {
    runOnly?: RunOnly | TagValue[] | string[] | string;
    rules?: RuleObject;
    reporter?: ReporterVersion | string;
    resultTypes?: resultGroups[];
    selectors?: boolean;
    ancestry?: boolean;
    xpath?: boolean;
    absolutePaths?: boolean;
    iframes?: boolean;
    elementRef?: boolean;
    frameWaitTime?: number;
    preload?: boolean;
    performanceTimer?: boolean;
    pingWaitTime?: number;
  }
...

I get this horribly frustrating error that seems to have been in quicktype for years, with no way to diagnose what is going on, and no way to fix it:

Error: Internal error: Defined value expected, but got undefined.

And now the web site no longer even supports TypeScript input, so it seems someone isn't telling us something. 🤔

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants