Equivalent of PHP Die(): how to stop function's execution on server - meteor

I am building a Meteor application with some custom authentication in addition to the built-in accounts MDG package.
I want to have a function I call at the front of Meteor methods to verify authentication. If authentication fails, I would like to do the equivalent of PHP's die() function - return a message and stop execution.
I could always do something like this: if(!checkAuth()) return "Not Authenticated", however it would be nice if I could just do checkAuth() and that function takes care of stopping execution if correct permissions are not met.
Is there a way to do this?

The easy way is to throw a new Meteor.Error. If not caught it will stop the currently running function, and if it is thrown from a method or a subscription it will appear on the client-side.
function checkAuth(user) {
if(!isAuthenticated(user)) {
throw new Meteor.Error('not-authenticated', 'Users need to be authenticated to do foo')
}
}
The above thrown error server-side will appear on the client with the reason and the details. It allows you to do custom error handling tailored to whatever is happening. If any other kind of error is thrown, it will appear as "500 Internal server error".
Note that this mechanism is similar to check. You could even use a custom Match pattern :
check(user, MyPatterns.authenticatedUser)

Related

How to log Error Message Contents in Rebus?

Is there anyway to log message contents when an exception occurs?
I looked at various logging extensions but they are just logging CorrelationId. And message contents are not available.
There is a CurrentMessge property in MessageContext, but that is not available at the time logger writes the exception.
I tried to handle PoisonMessage Event, which allows me to log the message contents.
public static void OnPoisonMessage(IBus bus, ReceivedTransportMessage receivedTransportMessage, Rebus.Bus.PoisonMessageInfo poisonMessageInfo) {
var message = new JsonMessageSerializer().Deserialize(receivedTransportMessage);
Log.Error("{#messageType} failed {#message}", message.Messages[0].GetType(), message);
}
This works great, but now I have two errors in the log one coming from my handler and the other coming from logger.
I am wondering if there is a better way to handle this requirement.
If your requirement is to simply log the message contents as JSON, I think you've found the right way to do it - at least that's the way I would have done it.
I'm curious though as to what problem you're solving by logging the message contents - you are aware of the fact that the failing message will end up in an error queue where you can inspect it?
If you're using MSMQ, you can inspect JSON-serialized messages using Rebus' Snoop-tool, which is a simple MSMQ inspector. It will also allow you to move the message back into the input queue where it failed ("return to source queue")
A good way to monitor your Rebus installation is to set up some kind of alerts when something arrives in an error queue, and then you can look at the message (which event includes the caught exceptions in a special header) and then resolve the situation from there.

In Meteor Methods this.connection is always undefined

I am trying to implement some methods for a DDP API, for use with a C# remote client.
Now, I want to be able to track the connection to implement some type of persistent session, to this end, id hope to be able to use the session id given by DDP on connection, example:
{
"msg": "connected",
"session": "CmnXKZ34aqSnEqscR"
}
After reading the documentation, I see that inside meteor methods, I can access the current connection using "this.connection", however, I always get an undefined "this.connection".
Was it removed? If so, how can i access it now?
PS: I dont want to login as a user and access this.userId, since the app I want to create should not login, but actually just get a document id and do work associated with that, including changes to other collections, but all, regarding ONLY this id, and I dont want to have to include this id every time I call a function, since, this could possibly lead security problems if anyone can just send any id. The app would ideally do a simple login, then associate token details with his "session".
Changing from:
() => { this.connection; }
to:
function() { this.connection; }
solves the problem from me. Based on a comment in the accepted answer.
The C# client on github has a few bugs with it as it doesn't follow the DDP spec exactly. When you send commands to it to connect and run a call, it usually sends the '.call' too soon.
The method does work if you do it this way with this.connection on the server side Meteor method.
You need to make sure you send the method calls after you know that you are actually connected. This is what works at least with Meteor 0.8.2
I was using a file named ".next.js" to force meteor to use the newest unsupported javascript spec using a package.
Somehow this messed it up. Changed back to default javascript and it now works.
Thank you :)
init.coffee
Meteor.startup ->
# client init
if Meteor.isClient
Meteor.call "init"
methods.coffee
Meteor.methods
init: ->
console.log #connection.httpHeaders.host
it's that easy...

Deps.autorun says server function is undefined

I've never took the time/chance to really understand the scope of Deps.autorun... so here I am again with the same problem that had bothered me many times (previously, I always found a workaround and bypass the issue)... anyways, basically, I have a function defined on the server side:
serverFunc = function() {}
and on the client side, I do
Deps.autorun(function() { var test = serverFunc(); }
I get error message say serverFunc is not defined.
Can someone kindly help me understanding why this is happening?
Thanks so much!
Deps.autorun() always runs once, then reruns the function whenever any of the dependencies that are tracked changes. These dependencies usually need to be set up as Meteor reactive data sources. A simple function being undefined on the client and then defined on the server isn't enough to retrigger.
If you want functions defined only on the server to be called from the client, you have to do two things:
On the server, put the function in Meteor.methods
On the client, use Meteor.call
Otherwise, a function defined only on the server does not exist on the client, and calling it on the client will throw an error as calling an undefined function.

In meteor, are successive operations on the server synchronous?

If, as part of a single Meteor.call, I make two calls to the database on the server, will these happen synchronously or do I need to use a callback?
Meteor.methods({
reset: function(id) {
Players.remove(_id:id);
// Will the remove definitely have finished before the find?
Players.find();
...
}
From the docs:
In Meteor, your server code runs in a single thread per request, not in the asynchronous callback style typical of Node. We find the linear execution model a better fit for the typical server code in a Meteor application.
If you read the docs on docs.meteor.com/#remove
you can find this :
Blockquote
On the server, if you don't provide a callback, then remove blocks until the database acknowledges the write and then returns the number of removed documents, or throws an exception if something went wrong. If you do provide a callback, remove returns immediately. Once the remove completes, the callback is called with a single error argument in the case of failure, or a second argument indicating the number of removed documents if the remove was successful.
Blockquote
On the client, remove never blocks. If you do not provide a callback and the remove fails on the server, then Meteor will log a warning to the console. If you provide a callback, Meteor will call that function with an error argument if there was an error, or a second argument indicating the number of removed documents if the remove was successful.
So on server side you choose if you want it to run in a sync or async way, it depends if you send a callback or not.

hook_user not being called for 'login' operation

I've read in the drupal documentation that hook_user should be invoked for the login operation. To test this I've added a call to drupal_set_message at the top of my modules hook implementation and the only message I'm receiving is a call with 'load' as the $op.
I've confirmed that drupal_set_message can be called multiple times and it doesn't erase the previous message, so I'm confident that hook_user is only being invoked the one time.
Any good reasons for why hook_user isn't being invoked with 'login' as an operation when I'm logging in?
Drupal version is 6 and my module is called "favequest_favorites" its implementation of hook_user (for testing purposes) is:
function favequest_favorites_user($op, &$edit, &$user, $caterogy=NULL) {
drupal_set_message($op);
}
As is often the case I've tracked this down to the interaction of modules.
Do not use the "Login Destination" module if you plan on using hook_user in your modules.
It bails out before all other modules may have had a chance to execute.
You've got a typo with the spelling of the "$caterogy" variable, but that shouldn't matter, since you're not using it in this test:
function favequest_favorites_user($op, &$edit, &$user, $caterogy=NULL) {
Using your code, I get four messages on login:
load
load
login
load
How about if you edit the user account? Do you get the "view" $op on the My Account page, and the "form" $op when you edit it?
Interesting that I don't get the "logout" $op when I log out--I assume that has something to do with a redirect, once I'm no longer authenticated.
See if you have a drupal_goto after you login.
http://drupal.org/node/228688
About drupal_set_message - The messages are saved into the session. When you login the session gets reset, and that might be the reason you don't see them. For a quick debug I recommend using devel module with dd function or system log messages.
Adi

Resources