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

Converting circular structure to JSON #339

Open
gerwinbrunner opened this issue Jul 4, 2019 · 3 comments
Open

Converting circular structure to JSON #339

gerwinbrunner opened this issue Jul 4, 2019 · 3 comments

Comments

@gerwinbrunner
Copy link

I'm trying to do a JSON.stringify on an error thrown by simpl-schema and I get the following error:

TypeError: Converting circular structure to JSON
    at evalCommandPromise.then (packages/shell-server/shell-server.js:249:21)
    at runBound (domain.js:314:12)
    at bound (domain.js:301:14)
    at defaultEval (repl.js:240:29)
    at ContextifyScript.Script.runInThisContext (vm.js:50:33)
    at repl:12:8
    at JSON.stringify (<anonymous>)

Any idea why this is and how to fix it?

This is a simplified scenario to illustrate the issue. It actually happens implicitly when an error in an Apollo resolver is caused by simpl-schema :(

This is the schema:

const AccountBaseFields = new SimpleSchema {
  name: { type: String },
  type: { type: String, allowedValues: ["paket", "ecommerce", "express"] },
  enabled: { type: Boolean, defaultValue: false },
};

Settings.schema = new SimpleSchema({
  userId: { type: String, unique: true },
  accounts: { type: Array, defaultValue: [] },
  "accounts.$": {type: AccountBaseFields}
});

This is the code:

      try {
        Settings.update({ _id: settings._id }, { $push: { accounts: { name: "test" } } });
      } catch (e) {
        console.error("error", e);
        console.error("error", JSON.stringify(e));
      }

This is the console log:

W20190704-17:01:27.703(2)? (STDERR) error { Error: Type is required (accounts.0.type) in settings update
W20190704-17:01:27.704(2)? (STDERR)     at getErrorObject (packages/aldeed:collection2/collection2.js:498:17)
W20190704-17:01:27.704(2)? (STDERR)     at doValidate (packages/aldeed:collection2/collection2.js:470:13)
W20190704-17:01:27.704(2)? (STDERR)     at Collection.Mongo.Collection.(anonymous function) [as update] (packages/aldeed:collection2/collection2.js:195:14)
W20190704-17:01:27.705(2)? (STDERR)     at createAccountPaket (imports/microservices/account-paket/server/resolvers.js:46:18)
W20190704-17:01:27.705(2)? (STDERR)     at field.resolve (/Users/ap/Documents/Data/Vilango/workspace/MeteorApps/DHLApp-v2/app/node_modules/apollo-server-core/node_modules/graphql-extensions/dist/index.js:133:26)
W20190704-17:01:27.705(2)? (STDERR)     at resolveFieldValueOrError (/Users/ap/Documents/Data/Vilango/workspace/MeteorApps/DHLApp-v2/app/node_modules/graphql/execution/execute.js:503:18)
W20190704-17:01:27.705(2)? (STDERR)     at resolveField (/Users/ap/Documents/Data/Vilango/workspace/MeteorApps/DHLApp-v2/app/node_modules/graphql/execution/execute.js:470:16)
W20190704-17:01:27.705(2)? (STDERR)     at /Users/ap/Documents/Data/Vilango/workspace/MeteorApps/DHLApp-v2/app/node_modules/graphql/execution/execute.js:280:18
W20190704-17:01:27.705(2)? (STDERR)     at /Users/ap/Documents/Data/Vilango/workspace/MeteorApps/DHLApp-v2/app/node_modules/graphql/jsutils/promiseReduce.js:23:10
W20190704-17:01:27.705(2)? (STDERR)     at Array.reduce (<anonymous>)
W20190704-17:01:27.706(2)? (STDERR)     at promiseReduce (/Users/ap/Documents/Data/Vilango/workspace/MeteorApps/DHLApp-v2/app/node_modules/graphql/jsutils/promiseReduce.js:20:17)
W20190704-17:01:27.706(2)? (STDERR)     at executeFieldsSerially (/Users/ap/Documents/Data/Vilango/workspace/MeteorApps/DHLApp-v2/app/node_modules/graphql/execution/execute.js:277:37)
W20190704-17:01:27.706(2)? (STDERR)     at executeOperation (/Users/ap/Documents/Data/Vilango/workspace/MeteorApps/DHLApp-v2/app/node_modules/graphql/execution/execute.js:255:55)
W20190704-17:01:27.706(2)? (STDERR)     at executeImpl (/Users/ap/Documents/Data/Vilango/workspace/MeteorApps/DHLApp-v2/app/node_modules/graphql/execution/execute.js:102:14)
W20190704-17:01:27.706(2)? (STDERR)     at Object.execute (/Users/ap/Documents/Data/Vilango/workspace/MeteorApps/DHLApp-v2/app/node_modules/graphql/execution/execute.js:62:35)
W20190704-17:01:27.706(2)? (STDERR)     at /Users/ap/Documents/Data/Vilango/workspace/MeteorApps/DHLApp-v2/app/node_modules/apollo-server-core/dist/requestPipeline.js:239:46
W20190704-17:01:27.706(2)? (STDERR)   invalidKeys: 
W20190704-17:01:27.706(2)? (STDERR)    [ { name: 'accounts.0.type', type: 'required', value: undefined } ],
W20190704-17:01:27.706(2)? (STDERR)   validationContext: 
W20190704-17:01:27.706(2)? (STDERR)    ValidationContext {
W20190704-17:01:27.707(2)? (STDERR)      _simpleSchema: 
W20190704-17:01:27.707(2)? (STDERR)       SimpleSchema {
W20190704-17:01:27.707(2)? (STDERR)         pick: [Function: pickOrOmit],
W20190704-17:01:27.707(2)? (STDERR)         omit: [Function: pickOrOmit],
W20190704-17:01:27.707(2)? (STDERR)         _constructorOptions: [Object],
W20190704-17:01:27.707(2)? (STDERR)         _validators: [],
W20190704-17:01:27.707(2)? (STDERR)         _docValidators: [],
W20190704-17:01:27.707(2)? (STDERR)         _validationContexts: [Object],
W20190704-17:01:27.707(2)? (STDERR)         _cleanOptions: [Object],
W20190704-17:01:27.707(2)? (STDERR)         _schema: [Object],
W20190704-17:01:27.707(2)? (STDERR)         _depsLabels: {},
W20190704-17:01:27.707(2)? (STDERR)         _schemaKeys: [Array],
W20190704-17:01:27.708(2)? (STDERR)         _autoValues: [Array],
W20190704-17:01:27.708(2)? (STDERR)         _blackboxKeys: [],
W20190704-17:01:27.708(2)? (STDERR)         _firstLevelSchemaKeys: [Array],
W20190704-17:01:27.708(2)? (STDERR)         _objectKeys: [Object],
W20190704-17:01:27.708(2)? (STDERR)         messageBox: [Object],
W20190704-17:01:27.708(2)? (STDERR)         version: 2 },
W20190704-17:01:27.708(2)? (STDERR)      _schema: { userId: [Object], accounts: [Object], 'accounts.$': [Object] },
W20190704-17:01:27.708(2)? (STDERR)      _schemaKeys: [ 'userId', 'accounts', 'accounts.$' ],
W20190704-17:01:27.708(2)? (STDERR)      _validationErrors: [ [Object] ],
W20190704-17:01:27.708(2)? (STDERR)      _deps: {} },
W20190704-17:01:27.708(2)? (STDERR)   sanitizedError: 
W20190704-17:01:27.709(2)? (STDERR)    { Error: Type is required (accounts.0.type) in settings update [400]
W20190704-17:01:27.709(2)? (STDERR)     at getErrorObject (packages/aldeed:collection2/collection2.js:504:28)
W20190704-17:01:27.709(2)? (STDERR)     at doValidate (packages/aldeed:collection2/collection2.js:470:13)
W20190704-17:01:27.709(2)? (STDERR)     at Collection.Mongo.Collection.(anonymous function) [as update] (packages/aldeed:collection2/collection2.js:195:14)
W20190704-17:01:27.709(2)? (STDERR)     at createAccountPaket (imports/microservices/account-paket/server/resolvers.js:46:18)
W20190704-17:01:27.709(2)? (STDERR)     at field.resolve (/Users/ap/Documents/Data/Vilango/workspace/MeteorApps/DHLApp-v2/app/node_modules/apollo-server-core/node_modules/graphql-extensions/dist/index.js:133:26)
W20190704-17:01:27.709(2)? (STDERR)     at resolveFieldValueOrError (/Users/ap/Documents/Data/Vilango/workspace/MeteorApps/DHLApp-v2/app/node_modules/graphql/execution/execute.js:503:18)
W20190704-17:01:27.709(2)? (STDERR)     at resolveField (/Users/ap/Documents/Data/Vilango/workspace/MeteorApps/DHLApp-v2/app/node_modules/graphql/execution/execute.js:470:16)
W20190704-17:01:27.709(2)? (STDERR)     at /Users/ap/Documents/Data/Vilango/workspace/MeteorApps/DHLApp-v2/app/node_modules/graphql/execution/execute.js:280:18
W20190704-17:01:27.709(2)? (STDERR)     at /Users/ap/Documents/Data/Vilango/workspace/MeteorApps/DHLApp-v2/app/node_modules/graphql/jsutils/promiseReduce.js:23:10
W20190704-17:01:27.709(2)? (STDERR)     at Array.reduce (<anonymous>)
W20190704-17:01:27.712(2)? (STDERR)     at promiseReduce (/Users/ap/Documents/Data/Vilango/workspace/MeteorApps/DHLApp-v2/app/node_modules/graphql/jsutils/promiseReduce.js:20:17)
W20190704-17:01:27.712(2)? (STDERR)     at executeFieldsSerially (/Users/ap/Documents/Data/Vilango/workspace/MeteorApps/DHLApp-v2/app/node_modules/graphql/execution/execute.js:277:37)
W20190704-17:01:27.712(2)? (STDERR)     at executeOperation (/Users/ap/Documents/Data/Vilango/workspace/MeteorApps/DHLApp-v2/app/node_modules/graphql/execution/execute.js:255:55)
W20190704-17:01:27.712(2)? (STDERR)     at executeImpl (/Users/ap/Documents/Data/Vilango/workspace/MeteorApps/DHLApp-v2/app/node_modules/graphql/execution/execute.js:102:14)
W20190704-17:01:27.712(2)? (STDERR)     at Object.execute (/Users/ap/Documents/Data/Vilango/workspace/MeteorApps/DHLApp-v2/app/node_modules/graphql/execution/execute.js:62:35)
W20190704-17:01:27.713(2)? (STDERR)     at /Users/ap/Documents/Data/Vilango/workspace/MeteorApps/DHLApp-v2/app/node_modules/apollo-server-core/dist/requestPipeline.js:239:46
W20190704-17:01:27.713(2)? (STDERR)      isClientSafe: true,
W20190704-17:01:27.713(2)? (STDERR)      error: 400,
W20190704-17:01:27.713(2)? (STDERR)      reason: 'Type is required (accounts.0.type) in settings update',
W20190704-17:01:27.713(2)? (STDERR)      details: '[{"name":"accounts.0.type","type":"required"}]',
W20190704-17:01:27.713(2)? (STDERR)      message: 'Type is required (accounts.0.type) in settings update [400]',
W20190704-17:01:27.713(2)? (STDERR)      errorType: 'Meteor.Error' } }
@coagmano
Copy link
Contributor

coagmano commented Jul 5, 2019

From the console.log, it looks like everything is fine.

I assume you're using Collection2 as well?
Have you tried just calling Settings.schema.validate directly to see if the error is coming from simpl-schema or from collection2?

From a quick shell test using:

try { 
  Settings.schema.validate(
    { $push: { accounts: { name: "test" } } },
    { modifier: true }
  ) 
} catch (e) { 
  console.log(JSON.stringify(e)) 
}

I got no error in the shell and this in the console:

I20190705-14:20:19.995(10)? {"isClientSafe":true,"error":"validation-error","details":[{"name":"accounts.0.type","type":"required","message":"Type is required"},{"name":"accounts.0.enabled","type":"required","message":"Enabled is required"}],"message":"[Type is required]","errorType":"Meteor.Error"}

@gerwinbrunner
Copy link
Author

gerwinbrunner commented Jul 5, 2019

Yes, I do use collection2.

The Settings.schema.validate call does raise an exception. it just returns an object as in your case:
I20190705-07:52:25.441(2)? {"errorType":"ClientError","name":"ClientError","error":"validation-error","details":[{"name":"accounts.0.auth.ekpNumber","value":"22222222222","type":"maxString","max":10,"message":"DHL EKP Number cannot exceed 10 characters"},{"name":"accounts.0.enabled","type":"required","message":"Enabled is required"}]}

When I remove the try... catch... from your example.
The error gets thrown in the resolver and then passed to the client correctly without the Converting circular structure to JSON problem occuring.

So validate behaves correctly - the update does not. Strange.

@aldeed
Copy link
Collaborator

aldeed commented Aug 27, 2019

Most likely the culprit is this in collection2: https://github.com/aldeed/meteor-collection2/blob/master/package/collection2/collection2.js#L503-L505

This is done for use in Meteor methods, which will return only the sanitized error to the client.

Or perhaps error.validationContext is circular.

For Apollo, you could probably add a custom error formatter function that returns error.sanitizedError instead of error and then it would not be circular. I don't know that there would really be any way to fix this, though, unless anyone has ideas.

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

3 participants