2

I am not sure if I am just doing something wrong or if this is actually not working. I want to display the original publication error on the client, in case I catched one:

Meteor.publish('somePub', function (args) {
  const self = this
  try {
    // ... publication logic
  catch (pubErr) {
    self.error(pubErr)
  }
})

On the client I am "catching" this error via the onStop callback:

Meteor.subscribe('somePub', args, { 
  onStop: function (e) {
    // display e to user
  }
})

However, while on the server the pubErr is a Meteor.Error and according to the documentation it should be sent to the client, the client just receives a generic sanitized error message:

on the server

{
  stack: "useful stack of actual method calls",
  error: "somePub.failed", 
  reason: "somePub.invalidArguments", 
  details: { arg: undefined }
}

on the client

{
  stack: "long list of ddp-message calls",
  isClientSafe: true, 
  error: 500, 
  reason: "Internal server error", 
  details: undefined, 
  message: "Internal server error [500]", 
  errorType: "Meteor.Error"
}

Note: I also tried to add the error to itself as sanitizedError field, as in the documentation mentioned, but no success either.

Am I missing something here?

Jankapunkt
  • 8,128
  • 4
  • 30
  • 59
  • Good question. Never ran into a need for this before. What actually happens when you don't catch the error? In method calls it is common to just throw exceptions and they will be sent to the client. Is that not the same in publications? Meaning, if you don't try-catch the exception the client will receive even less meaningful information? – Christian Fritz Aug 13 '20 at 21:36
  • Unfortunately it results in the same generic sanitized 500 error. – Jankapunkt Aug 13 '20 at 21:50
  • What happens when you manually create a new `Meteor.Error` object rather than forwarding the `pubErr`? Also, what do you use to cause the publication error? -- just so others can reproduce. – Christian Fritz Aug 13 '20 at 22:20
  • Thank you, a reproduction on a clean project worked so I searched for the issue and found it, I will add it as an answer here, in case others face a similar issue. – Jankapunkt Aug 14 '20 at 08:18

1 Answers1

0

Actually I found the answer to the issue after being pointed into the right direction.

The example code works fine on a new project, so I checked why not in my project and I found, that I did not surround the arguments validation using SimpleSchema by the try/catch (unfortunately my question was poorly designed as it missed this important fact, mainly because I abstracted away the schema validation from the publication creation):

Meteor.publish('somePub', function (args) {
  pubSchema.validate(args) // throws on fail

  const self = this
  try {
    // ... publication logic
  catch (pubErr) {
    self.error(pubErr)
  }
})

So I thought this could not be the issue's source but here is the thing: Simple Schema is not a pure Meteor package but a NPM package and won't throw a Meteor.Error but a custom instance of Error, that actually has the same attributes (error, errorType, details) like a Meteor.Error, see this part of the source code of a validation context.

So in order to pass the correct information of a SimpleSchema validation error to the client you should

  • wrap it in a try/catch
  • add the isClientSafe flag to it
  • alternatively convert it to a Meteor.Error
  • Attach a custom Meteor.Error as sanitizedError property to it
Jankapunkt
  • 8,128
  • 4
  • 30
  • 59