I'd like to somehow find out which CFC is calling my method.
I have a logging CFC which is called by many different CFC's. On this logging CFC there's a need to store which CFC called for the log.
Whilst I could simply pass the CFC name as an argument to my log.cfc, I find this to be a repetitive task, that might not be necessary, if I somehow could find out "who's" calling the method on log.cfc
Is there any programmatic way of achieving this?
Thanks in advance
Update: As Richard Tingle's answer points out, since CF10 you can use CallStackGet(), which is better than throwing a dummy exception.
Original answer: The easiest way is to throw a dummy exception and immediately catch it. But this has the downside of making a dummy exception show up in your debug output. For me, this was a deal-breaker, so I wrote the following code (based off of this code on cflib). I wanted to create an object that is similar to a cfcatch object, so that I could use it in places that expected a cfcatch object.
Note: You may have to adjust this code a bit to make it work in CF8 or earlier. I don't think the {...} syntax for creating object was supported prior to CF9.
StackTrace = {
Type= 'StackTrace',
Detail= '',
Message= 'This is not a real exception. It is only used to generate debugging information.',
TagContext= ArrayNew(1)
};
j = CreateObject("java","java.lang.Thread").currentThread().getStackTrace();
for (i=1; i LTE ArrayLen(j); i++)
{
if(REFindNoCase("\.cf[cm]$", j[i].getFileName())) {
ArrayAppend(StackTrace.TagContext, {
Line= j[i].getLineNumber(),
Column= 0,
Template= j[i].getFileName()
});
}
}
From ColdFusion 10 there is now a function to do this callStackGet()
For example the following code will dump the stack trace to D:/web/cfdump.txt
<cfdump var="#callStackGet()#" output="D:/web/cfdump.txt">
One kludgey way is to throw/catch a custom error and parse the stack trace. Here are some examples
http://www.bennadel.com/blog/406-Determining-Which-Function-Called-This-Function-Using-ColdFusion-.htm
http://coldfusion.dzone.com/news/what-function-called-my-functi
I don't know of a method to do directly what you are asking, maybe someone else does.
However, I believe you could get the stack trace and create a function to parse the last method call.
This function on cflib will get you the stack trace.
Related
how to debug built-in js files in v8.(i.e v8natives.js,array.js,string.js)
Please let me know any documentations or insights regarding this.
Thanks
You can call %GlobalPrint("hello");, the argument must be converted to a string before you pass it (So don't call %GlobalPrint(1) but %GlobalPrint("1") and it only takes one argument.
List of the functions you can call is at runtime/runtime.h (with their implementations and possibly some documentation in the runtime .cc files), these are on top of the normal javascript functions you can call like JSON.parse.
For example in the apinatives.js file:
function InstantiateFunction(data, name) {
// We need a reference to kApiFunctionCache in the stack frame
// if we need to bail out from a stack overflow.
%GlobalPrint("Called instantiate function with ");
%DebugPrint(data);
%GlobalPrint("and");
%DebugPrint(name);
...
}
So, I was attempting to do something like the following:
if(Meteor.isServer){
Meteor.methods({connect_to_api: function(vars){
// get data from remote API
return data;
}});
}
if(Meteor.isClient){
Template.myTpl.content = function(){
Meteor.call('connect_to_api', vars, function(err,data){
Session.set('placeholder', data);
});
return Session.get('placeholder');
};
}
This seemed to be working fine, but, of course, now breaks in 0.5.9 as the Session object has been removed from the server. How in the world do you now create a reactive Template that uses a server-only (stuff we don't want loading on the client) method call and get data back from that Method call. You can't put any Session references in the callback function because it doesn't exist on the server, and I don't know of any other reactive data sources available for this scenario.
I'm pretty new to Meteor, so I'm really trying to pin down best-practices stuff that has the best chance of being future-proof. Apparently the above implementation was not it.
EDIT: To clarify, this is not a problem of when I'm returning from the Template function. This is a problem of Session existing on the server. The above code will generate the following error message on the server:
Exception while invoking method 'connect_to_api' ReferenceError: Session is not defined
at Meteor.methods.connect_to_api (path/to/file.js:#:#)
at _.extend.protocol_handlers.method.exception ... etc etc
Setting the session in the callback seems to work fine, see this project I created on github: https://github.com/jtblin/meteor_session_test. In this example, I return data in a server method, and set it in the session in the callback.
There are 2 issues with your code:
1) Missing closing brace placement in Meteor.methods. The code should be:
Meteor.methods({
connect_to_api: function(vars) {
// get data from remote API
return data;
}
});
2) As explained above, you return the value in the session, before the callback is completed, i.e. before the callback method had the time to set the session variable. I guess this is why you don't see any data in the session variable yet.
I feel like an idiot (not the first time, not the last). Thanks to jtblin for showing me that Session.set does indeed work in the callback, I went back and scoured my Meteor.method function. Turns out there was one spot buried in the code where I was using Session.get which was what was throwing the error. Once I passed that value in from the client rather than trying to get it in the method itself, all was right with the world.
Oh, and you can indeed order things as above without issue.
Going from Joomla 2.5 to 3.0 with my extension, I'm struggling with how to do the DB error handling (since GetErrorNum is deprecated, see also Joomla! JDatabase::getErrorNum() is deprecated, use exception handling instead).
The way that seems to be the one to go according to the question linked above, is to add the following code for each db->query() code:
if (!$db->query()) {
throw new Exception($db->getErrorMsg());
}
In my opinion, that makes DB error handling more awkward than it was before. So far, I simply called a checkDBError() function after a DB call, which queried the ErrorNum and handled any possible error accordingly.
That was independent from how the DB query was actually triggered - there are different ways to do that, and different results on an error: $db->loadResult() returns null on error, $db->query() returns false. So there will now be different checks for different DB access types.
Isn't there any generic way to handle this, e.g. a way to tell Joomla to throw some exception on DB problems? Or do I have to write my own wrapper around the DatabaseDriver to achieve that? Or am I maybe missing something obvious?
Or should I just ignore the deprecation warning for now and continue with using getErrorNum()? I'd like to make my extension future-proof, but I also don't want to clutter it too much with awkward error handling logic.
Just found this discussion: https://groups.google.com/forum/#!msg/joomla-dev-general/O-Hp0L6UGcM/XuWLqu2vhzcJ
As I interpret it, there is that deprecation warning, but there is no proper replacement yet anyway...
Unless somebody points out any other proper documentation of how to do it in 3.0, I will keep to the getErrorNum method of doing stuff...
Get getErrorNum() function will solve your problem....
$result = $db->loadResult();
// Check for a database error.
if ($db->getErrorNum())
{
JFactory::getApplication()->enqueueMessage($db->getErrorMsg());
return false;
}
Does anyone have the faintest idea what this error means please and how to resolve it? All my research is drawing a blank, I can see how to set it on MSDN but it doesn't explain it in a way that explains to me what the issue is. If I remove some of my LINQ queries to set viewbag items then it seems to resolve it but the moment I set new ones and pass them into my view to generate a mail for MVCMailer it comes back. Not sure if its a viewbag issue or simply that I am calling too many linq queries to generate them to pass to the view.
I am very stuck (again)..........
Cheers,
Steve.
DbLimitExpression requires a collection argument.
Parameter name: argument
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.ArgumentException: DbLimitExpression requires a collection argument.
Parameter name: argument
An example of the code is:
var VBSalutation = from A in context.Salutations
where A.SalutationId == policytransaction.SalutationId
select A.SalutationName;
ViewBag.Salutation = VBSalutation.FirstOrDefault();
This is repeated for various parameters and then passed to the view.
Well, I faced a similar problem and solved it. Problem was in WHERE clause: data type of left side equal operator (=) sign was not matching with data type of right side. So in your scenario:
where A.SalutationId == policytransaction.SalutationId
SalutationID of A might be an INT and SalutationId of policytransaction might be a string (This is how it was in my case).
I solved it by assigning policytransaction.SalutationId to an Int variable and using it:
int myIntVariable = Convert.ToInt16(policytransaction.SalutationId);
...//some code here
where A.SalutationId == myIntVariable;
Please also note that you cannot directly cast your variables directly in Linq else you'll get an error "LINQ to Entities does not recognize the method". You'll have to use a temp variable and then apply the where clause.
Try ViewBag.Salutation = VBSalutation.SingleOrDefault();
Even though I've been using mootools for a while now, I haven't really gotten into playing with the natives yet. Currently I'm trying to extend events by adding a custom addEvent method beside the original. I did that using the following code(copied from mootools core)
Native.implement([Element, Window, Document], {
addMyEvent:function(){/* code here */}
}
Now the problem is that I can't seem to figure out, how to properly overwrite the existing fireEvent method in a way that I can still call the orignal method after executing my own logic.
I could probably get the desired results with some ugly hacks but I'd prefer learning the elegant way :)
Update: Tried a couple of ugly hacks. None of them worked. Either I don't understand closures or I'm tweaking the wrong place. I tried saving Element.fireEvent to a temporary variable(with and without using closures), which I would then call from the overwritten fireEvent function(overwritten using Native.implement - the same as above). The result is an endless loop with fireEvent calling itself over and over again.
Update 2:
I followed the execution using firebug and it lead me to Native.genericize, which seems to act as a kind of proxy for the methods of native classes. So instead of referencing the actual fireEvent method, I referenced the proxy and that caused the infinite loop. Google didn't find any useful documentation about this and I'm a little wary about poking around under the hood when I don't completely understand how it works, so any help is much appreciated.
Update 3 - Original problem solved:
As I replied to Dimitar's comment below, I managed to solve the original problem by myself. I was trying to make a method for adding events that destroy themselves after a certain amount of executions. Although the original problem is solved, my question about extending natives remain.
Here's the finished code:
Native.implement([Element, Window, Document], {
addVolatileEvent:function(type,fn,counter,internal){
if(!counter)
counter=1;
var volatileFn=function(){
fn.run(arguments);
counter-=1;
if(counter<1)
{
this.removeEvent(type,volatileFn);
}
}
this.addEvent(type,volatileFn,internal);
}
});
is the name right? That's the best I could come up with my limited vocabulary.
document.id("clicker").addEvents({
"boobies": function() {
console.info("nipple police");
this.store("boobies", (this.retrieve("boobies")) ? this.retrieve("boobies") + 1 : 1);
if (this.retrieve("boobies") == 5)
this.removeEvents("boobies");
},
"click": function() {
// original function can callback boobies "even"
this.fireEvent("boobies");
// do usual stuff.
}
});
adding a simple event handler that counts the number of iterations it has gone through and then self-destroys.
think of events as simple callbacks under a particular key, some of which are bound to particular events that get fired up.
using element storage is always advisable if possible - it allows you to share data on the same element between different scopes w/o complex punctures or global variables.
Natives should not be modded like so, just do:
Element.implement({
newMethod: function() {
// this being the element
return this;
}
});
document.id("clicker").newMethod();
unless, of course, you need to define something that applies to window or document as well.