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 parsing schema file with a minimum value for a number #86

Closed
lschierer opened this issue Oct 24, 2024 · 12 comments
Closed

error parsing schema file with a minimum value for a number #86

lschierer opened this issue Oct 24, 2024 · 12 comments

Comments

@lschierer
Copy link

given a schema file that has a component that sets a minimum value for something of type number, OpenAPI::Modern will refuse to load it saying "got ambiguous type, not number" on the minimum, then "not all properties are valid" on the object containing it.
openapi.yaml.txt

I reduced my actual API file down enough to show the error fairly clearly without lots of extraneous stuff in it. This API file validates fine with both the SwaggerUI viewer and the ibm-openapi-validator (though it does show some warnings with the latter, it shows no errors).

@lschierer
Copy link
Author

The thing is that I may have other similar false parsing bugs, but as this object is at the root of the tree of components, it is really difficult to figure out from the limited information in the error if the rest of the tree is failing because this did, or for other reasons as well. I can provide the entire yaml file if you'd like, but I figured a more minimal reproduction might be best to start with.

@lschierer
Copy link
Author

lschierer commented Oct 24, 2024

I tried reading the spec in several different ways, ultimately settling on a variation of some example code you provided,

my $OpenAPISchemaCache;
sub get_openapi ($openapi_filename) {
    my $newTemp = 0;
    if(not defined($OpenAPISchemaCache)) {
      $OpenAPISchemaCache = File::Temp->new();
      $newTemp = true;
    }
    my $serialized_file = Path::Tiny::path($OpenAPISchemaCache);
    my $openapi_file = Path::Tiny::path($openapi_filename);
    my $openapi;
    if ($newTemp or $serialized_file->stat->mtime < $openapi_file->stat->mtime) {
      $openapi = OpenAPI::Modern->new(
        openapi_uri => '/',
        openapi_schema => Load($openapi_file->slurp_raw), # your openapi document
      );
      my $frozen = Sereal::Encoder->new({ freeze_callbacks => 1 })->encode($openapi);
      $serialized_file->spew_raw($frozen);
    }
    else {
      my $frozen = $serialized_file->slurp_raw;
      $openapi = Sereal::Decoder->new->decode($frozen);
    }

    return $openapi;
  }

@karenetheridge
Copy link
Owner

  • what is the exact error you get (the location in the schema is significant)
  • your code snippet isn't enough to reproduce the issue -- what matters is how the text file is being read in and passed to the openapi_schema parameter in the constructor.

My next questions will be what perl version you are using, and the module version of whatever is turning the yaml file into a hashref, because that's what's mangling the number(s) in your schema.

@lschierer
Copy link
Author

lschierer commented Oct 24, 2024

perl 5, version 40 on OSX.

the file doing the reading is here (note the branch in that link, the main branch of that repository doesn't have it).

the path to the file is constructed at line 75 and the function to read in the file is immediately on the next line. I'm not yet doing anything with the result, I currently still have the code in place using the document_filename parameter instead, but while that doesn't produce any errors, it also results in a program that apparently has an empty configuration object.

I'm running this locally with the command

dzil run script/EvonyWeb.pl daemon -m development

@lschierer
Copy link
Author

$ cpan -l | grep -i openapi
Use of uninitialized value $ExtUtils::MakeMaker::_version::version in concatenation (.) or string at (eval 2230) line 7, <FILE> line 142.
OpenAPI::Modern	0.072
JSON::Validator::Schema::OpenAPIv2	undef
JSON::Validator::Schema::OpenAPIv3	undef
JSON::Schema::Modern::Document::OpenAPI	0.072
JSON::Schema::Modern::Vocabulary::OpenAPI	0.072
Mojolicious::Plugin::OpenAPI	5.09
Mojolicious::Plugin::OpenAPI::Cors	undef
Mojolicious::Plugin::OpenAPI::Security	undef
Mojolicious::Plugin::OpenAPI::SpecRenderer	undef
Mojolicious::Plugin::OpenAPI::Parameters	undef
Mojolicious::Plugin::OpenAPI::Modern	0.012
$

as you can see I've tried a few different modules in my quest to first understand and second get something working. I'm fairly sure that most of these are not being loaded though:

lschiere@80a997121f31:~/src/schierer/Game-EvonyTKR$ dzil listdeps | grep -i openapi
Smartmatch is deprecated at (eval 1872) line 8, <GEN23> line 32.
Smartmatch is deprecated at (eval 1872) line 15, <GEN23> line 32.
Smartmatch is deprecated at (eval 1873) line 8, <GEN23> line 32.
Smartmatch is deprecated at (eval 1873) line 15, <GEN23> line 32.
Smartmatch is deprecated at (eval 1874) line 8, <GEN23> line 32.
Smartmatch is deprecated at (eval 1874) line 15, <GEN23> line 32.
Smartmatch is deprecated at (eval 1875) line 11, <GEN23> line 32.
Smartmatch is deprecated at (eval 1875) line 21, <GEN23> line 32.
JSON::Schema::Modern::Document::OpenAPI
Mojolicious::Plugin::OpenAPI::Modern
OpenAPI::Modern

@lschierer
Copy link
Author

the hashref would be coming from line 115. that Load function is from use YAML::XS qw{ LoadFile Load };

@lschierer
Copy link
Author

I added a script file which has just the loading stuff extracted out from the rest of the Web.pm file

@lschierer
Copy link
Author

I've also tried LoadFile($openapi_file) instead of the current Load($openapi_file->slurp_raw) that is there now. Both functions LoadFile and Load come from YAML::XS as I said. both versions of the loader do the same thing.

@lschierer
Copy link
Author

I changed the loading to

my $loadedFile = LoadFile($openapi_file);
      say Data::Printer::p($loadedFile);

      $openapi = OpenAPI::Modern->new(
        openapi_uri => '/',
        openapi_schema => $loadedFile, # your openapi document
      );

and the Data::Printer output looks like it imported a number to me.

@karenetheridge
Copy link
Owner

Ah, you're using YAML::XS. So you're bumping into a parsing problem that it has there, see

ingydotnet/yaml-libyaml-pm#110
ingydotnet/yaml-libyaml-pm#111
ingydotnet/yaml-libyaml-pm#112

The workaround, until this is fixed, is to use YAML::PP: my $schema = YAML::PP->new(boolean => 'JSON::PP')->load_file($filename);

You can see the effect of this with:

$; perl -MJSON::Schema::Modern::Utilities=get_type,is_type -MDevel::Peek -MYAML::XS=Load -wle'my $data = Load("---\nfoo: 1"); Dump($data->{foo}); print "type: ", get_type($data->{foo}); print "integer? ", 0+is_type($data->{foo}, "integer");'
SV = PVIV(0x123019238) at 0x12180b098
  REFCNT = 1
  FLAGS = (IOK,POK,pIOK,pPOK)
  IV = 1
  PV = 0x6000015591d0 "1"\0
  CUR = 1
  LEN = 16
type: ambiguous type
integer? 0

@karenetheridge karenetheridge transferred this issue from karenetheridge/OpenAPI-Modern Oct 24, 2024
@lschierer
Copy link
Author

Changing to YAML::PP did indeed get me past any issue. Since this seems to be a known bug with the YAML::XS folks, you can close this as it doesn't seem like there's anything for you to do except maybe document a compatibility limitation?

Thanks for the support!!

@karenetheridge
Copy link
Owner

Resolved in release 0.594, which is more forgiving of malformed numeric strings.

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

2 participants