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

Deserializing an enum with a missing value does not result in the default enum value #348

Closed
alycklama opened this issue May 4, 2021 · 2 comments

Comments

@alycklama
Copy link

I'm trying to make the following scenario work:

TypeV1

  • Contains an enum with initial 4 values: CAT, DOG, DUCK and UNKNOWN.
  • Default value for the enum is UNKNOWN.

TypeV2

  • Contains a subset of the previous enum: DOG and UNKNOWN.
  • Default value for the enum is UNKNOWN.

I'm serializing an object of TypeV1 with value DUCK and I try to deserialize it with TypeV2. I expected the value to be UNKNOWN. Why wouldn't this work? It results in the error below:

./node_modules/avsc/lib/types.js:546
    throw new Error(f('cannot read %s as %s', type, this));
    ^

Error: cannot read {"type":"enum","symbols":["CAT","DOG","DUCK","UNKNOWN"]} as {"type":"enum","symbols":["DOG","UNKNOWN"]}
    at EnumType.Type.createResolver (./node_modules/avsc/lib/types.js:546:11)
    at RecordType._update (./node_modules/avsc/lib/types.js:2366:30)
    at RecordType.Type.createResolver (./node_modules/avsc/lib/types.js:542:10)
    at main (./main.js:46:31)
    at Object.<anonymous> (./main.js:52:5)
    at Module._compile (internal/modules/cjs/loader.js:1063:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
    at Module.load (internal/modules/cjs/loader.js:928:32)
    at Function.Module._load (internal/modules/cjs/loader.js:769:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12)
const avro = require('avsc');

function main() {
    const typeV1 = avro.Type.forSchema({
        type: 'record',
        fields: [
            {
                name: 'kind',
                type: {
                    type: 'enum',
                    default: 'UNKNOWN',
                    symbols: [
                        'CAT',
                        'DOG',
                        'DUCK',
                        'UNKNOWN',
                    ]
                },
                default: 'UNKNOWN'
            }
        ]
    });

    const bufV1 = typeV1.toBuffer({kind: 'DUCK'}); // Encoded buffer.
    const valV1 = typeV1.fromBuffer(bufV1);
    console.log(valV1);

    const typeV2 = avro.Type.forSchema({
        type: 'record',
        fields: [
            {
                name: 'kind',
                type: {
                    type: 'enum',
                    default: 'UNKNOWN',
                    symbols: [
                        'DOG',
                        'UNKNOWN',
                    ]
                },
                default: 'UNKNOWN'
            }
        ]
    });

    const resolverV2 = typeV2.createResolver(typeV1);
    const valV2 = typeV2.fromBuffer(bufV1, resolverV2);
    console.log(valV2);
}

if (require.main === module) {
    main();
}
@mtth
Copy link
Owner

mtth commented May 6, 2021

Hi @alycklama. avsc doesn't support enum defaults yet.

FTR: #238 (comment)

@mtth
Copy link
Owner

mtth commented May 6, 2021

5.7.0, just released, supports enum defaults. Once you upgrade, the snippet above will produce the expected result.

@mtth mtth closed this as completed May 6, 2021
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