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

toJSON: Cannot read property 'prototype' of null at Function.toObject #730

Closed
tamird opened this Issue Mar 27, 2017 · 5 comments

Comments

Projects
None yet
2 participants
@tamird

tamird commented Mar 27, 2017

When calling MessageObject.toJSON(), I get the following error:

Cannot read property 'prototype' of null at Function.toObject

Which occurs in this function:

                TimeSeriesQueryRequest.toObject = function toObject(message, options) {
                    if (!options)
                        options = {};
                    var object = {};
                    if (options.arrays || options.defaults)
                        object.queries = [];
                    if (options.defaults) {
                        if ($util.Long) {
                            var long = new $util.Long(0, 0, false);
                            object.start_nanos = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                        } else
                            object.start_nanos = options.longs === String ? "0" : 0;
                        if ($util.Long) {
                            var long = new $util.Long(0, 0, false);
                            object.end_nanos = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                        } else
                            object.end_nanos = options.longs === String ? "0" : 0;
                        if ($util.Long) {
                            var long = new $util.Long(0, 0, false);
                            object.sample_nanos = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                        } else
                            object.sample_nanos = options.longs === String ? "0" : 0;
                    }
                    if (message.start_nanos != null && message.hasOwnProperty("start_nanos"))
                        if (typeof message.start_nanos === "number")
                            object.start_nanos = options.longs === String ? String(message.start_nanos) : message.start_nanos;
                        else
                            object.start_nanos = options.longs === String ? $util.Long.prototype.toString.call(message.start_nanos) : options.longs === Number ? new $util.LongBits(message.start_nanos.low >>> 0, message.start_nanos.high >>> 0).toNumber() : message.start_nanos; // <-- unguarded access to `$util.Long`!!
                    if (message.end_nanos != null && message.hasOwnProperty("end_nanos"))
                        if (typeof message.end_nanos === "number")
                            object.end_nanos = options.longs === String ? String(message.end_nanos) : message.end_nanos;
                        else
                            object.end_nanos = options.longs === String ? $util.Long.prototype.toString.call(message.end_nanos) : options.longs === Number ? new $util.LongBits(message.end_nanos.low >>> 0, message.end_nanos.high >>> 0).toNumber() : message.end_nanos;
                    if (message.queries && message.queries.length) {
                        object.queries = [];
                        for (var j = 0; j < message.queries.length; ++j)
                            object.queries[j] = $root.cockroach.ts.tspb.Query.toObject(message.queries[j], options);
                    }
                    if (message.sample_nanos != null && message.hasOwnProperty("sample_nanos"))
                        if (typeof message.sample_nanos === "number")
                            object.sample_nanos = options.longs === String ? String(message.sample_nanos) : message.sample_nanos;
                        else
                            object.sample_nanos = options.longs === String ? $util.Long.prototype.toString.call(message.sample_nanos) : options.longs === Number ? new $util.LongBits(message.sample_nanos.low >>> 0, message.sample_nanos.high >>> 0).toNumber() : message.sample_nanos;
                    return object;
                };

This code was generated with --strict-long, so I'm not really sure why util.Long is undefined, or why any of the code paths above need to be guarded with if ($util.Long) {.

@dcodeIO

This comment has been minimized.

Owner

dcodeIO commented Mar 27, 2017

--strict-long has no effect on generated code. It just makes sure to document long fields as Long instead of number|Long for TypeScript. The CLI basically just wraps up what the encoder, decoder and converter generate at runtime anyway in a reflection based scenario.

This code was generated with --strict-long, so I'm not really sure why [...] any of the code paths above need to be guarded with if ($util.Long) {.

Currently, generated code aims to remain compatible with any configuration (with or without long.js), in case it is shared or otherwise depended upon by another application.

@tamird

This comment has been minimized.

tamird commented Mar 27, 2017

That's fine; what's the story with $util.Long being undefined?

@dcodeIO

This comment has been minimized.

Owner

dcodeIO commented Mar 27, 2017

That's fine; what's the story with $util.Long being undefined?

Looks like long.js isn't present. You can check this by evaluating protobuf.util.Long. If it's unset, you can also explicitly set it, like so:

protobuf.util.Long = require("long");
protobuf.configure();
@tamird

This comment has been minimized.

tamird commented Mar 27, 2017

long.js is present; I can do what you suggest, but why is it not being picked up automatically?

@dcodeIO

This comment has been minimized.

Owner

dcodeIO commented Mar 27, 2017

For reference, this is about how the process works:

  • inquire("long") (ref) tries to load the long library, which requires a global require function to be available
  • if it cannot be required, it looks for it in global.dcodeIO.Long and if it isn't there either, it sets protobuf.util.Long to null
  • AMD modules specify "long" as a dependency and it's set like shown above if it is available (ref)

Referring to the error you see: Long conversion to strings is available with long.js only. Conversion to (a possibly unsafe) number should work even if long.js isn't present.

dcodeIO added a commit that referenced this issue Mar 27, 2017

@tamird tamird closed this Mar 27, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment