CAPL code, putting delay in the code - delay

I have a CAPL test code that controls the start of CAN signal sending. My goal is to delay the start of the sending process.
My idea to do this is via a setTimer() function in combination with isTimerActive().
In general my code looks the following:
main() {
CANstart();
function_2();
function_3();
}
CANstart() {
SetTimer(Delay, 5000); //Timer initialization, set to be 5000ms
while (isTimerActive()==1) {
// this while loop avoids that the code is proceding while the settimer exception is being called and executed
}
StartCANTransmitting(); // After this function, jump back to main and proceed with function_2
}
on timer Delay {
// Do nothing, just wait
}
The program code above lead to being stuck at that point, CANoe does not response and the only way I can end the simulation is via taskmanager.
Further examination from my side lead to the conclusion that the timer need more time to process and is not executed at all.
Without the isTimerActive() function, the program code does not wait for the timer to finish and there is no delay at all. Seems like the code runs through without waiting for the exception.
Seems like CAPL handles loops very bad.
I check out stackoverflow and the following forum posts talk about very similar issues that I have without offering any working solutions:
CAPL Programming usage of Timer as a delay
Are timers running, while loops are active?
Delay function in CAPL apart from testwaitfortimeout()

I see a great deal of issues with your code. It actually does not feel like code at all, but more like pseudo-code. Does it compile on your CAPL browser?
main() {
CANstart();
function_2();
function_3();
}
If this is a function declaration, then it is missing both a type and a return value. In addition, when are you expecting main() to be executed?
The same applies to:
CANstart()
Let us make a step back. You need to delay the beginning of can transmitting. If you need to do so because you have code outside CANalyzer/CANoe running, then I suggest you call the application via command line (refer to the guide for more help).
If you need, however, to have blocks running in your setup configuration, like a Replay block, a Loggin block or whatever, I suggest you to do the following:
variables {
/* define your variables here. You need to define all messages you want to send and respective signal values if not defaulted */
message 0x12345678 msg1; // refer to CAPL guide on how to define message type variables
msTimer delay;
msTimer msgClock1;
}
on start {
/* when you hit the start measurements button (default F9) */
setTimer(delay, 5000); // also note your syntax is wrong in the example
}
on timer delay {
/* when timer expires, start sending messages */
output(msg1); // send your message
setTimer(msgClock1,250); // set timer for cyclic message sending
}
on timer msgClock1 {
/* this mimicks the behaviour of a IG block */
setTimer(msgClock1,250); // keep sending message
output(msg1)
}
Does this achieve your goal? Please feel free to ask for more details.

It appears that you have a problem with the while (isTimerActive()==1) { statement.
CAPL function int isTimerActive requires the parameters timer or mstimer variable and return values
1, if the timer is active otherwise 0.
You can check if the timer is active and the time to elapse in the following way.
timer t;
write("Active? %d", isTimerActive(t)); // writes 0
setTimer(t, 5);
write("Active? %d", isTimerActive(t)); // writes 1
write("Time to elapse: %d",timeToElapse(t)); // Writes 5
try adding the parameter timer at while (isTimerActive(Delay)==1) {
I would not suggest using the while statement instead you can use the timer directly to call the function StartCANTransmitting() and your Main() should be MainTest()
void MainTest()
{
TestModuleTitle("Sample Tests");
TestModuleDescription("This test module calls some test cases to demonstrate ");
CANstart();
if (TestGetVerdictLastTestCase() == 1)
Write("CANstart failed.");
else
Write("CANstart passed.");
}
testcase CANstart() {
// add info block to test case in report
TestReportAddMiscInfoBlock("Used Test Parameters");
TestReportAddMiscInfo("Max. voltage", "19.5 V");
TestReportAddMiscInfo("Max. current", "560 mA");
TestReportAddMiscInfo("StartCANTransmitting");
SetTimer(Delay, 5000); //Timer initialization, set to be 5000ms
}
on timer Delay {
StartCANTransmitting();
}

Related

How can I mitigate a race condition between the UI thread and a DispatcherTimer.Tick event?

I believe I have a race condition in this code sample but am unsure how to mitigate it.
My scenario is that XAsync() always runs on the UI thread. Within XAsync(), I set m_importantMemberVariable and then start a timer; there's a 1 second delay before the timer fires.
My concern is the timer's tick event calls a method on m_importantMemberVariable. However, in the 1 second interval between starting the timer and Tick firing, XAsync() could be called again and overwrite m_importantMemberVariable.
Code example:
task<void> BobViewModel::XAsync()
{
return create_task(CreateSomethingAsync())
.then([this](SomethingAsync^ aThing)
{
this->m_importantMemberVariable = aThing;
OnPropertyChanged("ImportantMemberVariable");
// Timer has 1 second delay.
this->m_myDispatcherTimer->Start();
}, task_continuation_context::use_current())
.then([activity](task<void> result)
{
// more continuations...
});
}
void BobViewModel::OnTimerTick(Object^, Object^)
{
// Stopping the timer and detaching the event handler
// so timer only fires once.
m_myDispatcherTimer->Stop();
m_myDispatcherTimer->Tick -= m_impressionTimerToken;
m_myDispatcherTimer = { 0 };
// * Possible race condition *
m_importantMemberVariable->DoImportantThing();
}
Question: Assuming I'm correct about a race condition, is there a way to mitigate it?
My understanding is the tick event would fire on the UI thread so synchronization primitives won't help (as the UI thread would already have access).
All your operations are on the UI thread, so they've already been serialized (synchronized) for you. A simple flag will suffice:
bool m_busy; // set to false in constructor
task<void> BobViewModel::XAsync()
{
if (m_busy)
return;
m_busy = true;
// the rest of your code...
}
void BobViewModel::OnTimerTick(Object^, Object^)
{
m_busy = false;
// the rest of your code...
}
Just make sure you handle any exceptions such that you set m_busy back to false if something goes horribly wrong.
The answer to this question suggests using compare_exchange_strong with a std::atomic to ensure only one thread executes a function at a time. The problems with that approach, for this question, are:
1. The DispatcherTimer Tick event fires outside of the task continuation block, and can fire after the continuation completes.
2. A constraint on this problem is for the timer to only fire once.
Some alternative solutions are:
Use compare_exchange_strong but replace DispatcherTimer with create_delayed_task
Assuming the work doesn't have to happen on the UI thread, you can use create_delayed_task to delay work within a task continuation.
task<void>
BobViewModel::UseImportantVariableAsync(
Object^ importantVariable
)
{
return create_delayed_task(
std::chrono::milliseconds(1000),
[importantVariable]()
{
importantMemberVariable->DoImportantThing();
});
}
Then, from the task continuation, simply:
return UseImportantVariableAsync(m_importantMemberVariable);
Use a lambda for the DispatcherTimer's Tick event and capture 'aThing' from the question's example (instead of referencing the member variable in the handler). To only fire the timer once, assign the DispathcerTimer.Tick handler within a std::call_once block so only the first caller gets to do it.

Sleeping in action script 2 using getTimer() method

How can I correctly perform something like sleep function using getTimer()? I need to do an action every 15 seconds. The code below doesn't work. I compile it with mtasc compiler on Linux.
class Tuto
{
static var lastMsg = 0;
static var msgInt = 15000;
static function main(mc)
{
if(getTimer() > lastMsg + msgInt)
{
trace("something");
lastMsg = getTimer();
}
}
}
The main instruction will be executed just once. You have to build some kind of loop or rely on the tick events sent by the player to execute your code continuously.
The basic options are:
while (true) { doSomething() }
this will execute forever, but remember that the flashplayer is single threaded so while that runs everything else will be frozen, UI and user inputs included. this is only "good" if you are building some heavy-processing tool that has no need of interacting with the user.
setInterval(doSomething, 15000)
this creates an interval that will call your function every X milliseconds. This is the simplest option and probably what you're looking for.
addEventListener(Event.ENTER_FRAME, doSomething)
this registers a listener for the ENTER_FRAME event of the Flash Player, which will be dispatched 30 times per second (by default). Inside that function you can check the current time with getTimer() and decide if it's time to execute your logic.

MFC/Activex and fire it's evnet after waitforsingleobject

my project is a dialog base and activeX container that have event .
when i call a function of activex and wait to fire it's event (with WaitForSingleObject), the application stops and the event doesn't happen until time-out, after time out it will happen.
void COcxTesDlg::OnBnClickedButton1()
{
hEvent = CreateEvent(NULL, TRUE, FALSE, L"testEvent");
ocxObj.ocxFunction();
DWORD res = ::WaitForSingleObject(hEvent, 10000);
if(res != WAIT_OBJECT_0)
AfxMessageBox(L"Time Out");
else
AfxMessageBox(L"before Time Out");
//--- to do some works after ocx event
//---
}
void COcxTesDlg::ocxEventFunc()
{
SetEvent(hEvent);
}
i always see 'Time Out' MessageBox, but if i don't call the WaitForSingleObject() the ocxEventFunc() happens sooner than 1000ms
i want to do some works after event without waiting a lot of time.
please help me.
Of course it does: you are asking your program to wait, and it waits.
Based on your description of what you are trying to do, your design is fundamentally broken: You are inside a message handler, in your main thread and you call WaitForSingleObject. That suspends execution of that thread, which handles all the user interface - and your program if you have only one thread - until the event is signaled or until the timeout expires.
You should rethink your design. Without knowing more it's not easy to suggest alternatives. One possibility is this:
Make a note of the start time (e.g. call GetTickCountEx and store the result).
Loop while start_time - current_time < timeout value. Inside the loop call WaitForSingleObject with 0 for the timeout. That call will not block and will return immediately: if it returns WAIT_OBJECT_0 then the OCX has completed. If it returns WAIT_TIMEOUT it means the OCX hasn't completed. You can then do whatever work you want.
You already have a function that is called when the event happens. Use it.
void COcxTesDlg::OnBnClickedButton1()
{
ocxObj.ocxFunction();
}
void COcxTesDlg::ocxEventFunc()
{
//--- to do some works after ocx event
//---
}

How to forcibly keep a Node.js process from terminating?

TL;DR
What is the best way to forcibly keep a Node.js process running, i.e., keep its event loop from running empty and hence keeping the process from terminating? The best solution I could come up with was this:
const SOME_HUGE_INTERVAL = 1 << 30;
setInterval(() => {}, SOME_HUGE_INTERVAL);
Which will keep an interval running without causing too much disturbance if you keep the interval period long enough.
Is there a better way to do it?
Long version of the question
I have a Node.js script using Edge.js to register a callback function so that it can be called from inside a DLL in .NET. This function will be called 1 time per second, sending a simple sequence number that should be printed to the console.
The Edge.js part is fine, everything is working. My only problem is that my Node.js process executes its script and after that it runs out of events to process. With its event loop empty, it just terminates, ignoring the fact that it should've kept running to be able to receive callbacks from the DLL.
My Node.js script:
var
edge = require('edge');
var foo = edge.func({
assemblyFile: 'cs.dll',
typeName: 'cs.MyClass',
methodName: 'Foo'
});
// The callback function that will be called from C# code:
function callback(sequence) {
console.info('Sequence:', sequence);
}
// Register for a callback:
foo({ callback: callback }, true);
// My hack to keep the process alive:
setInterval(function() {}, 60000);
My C# code (the DLL):
public class MyClass
{
Func<object, Task<object>> Callback;
void Bar()
{
int sequence = 1;
while (true)
{
Callback(sequence++);
Thread.Sleep(1000);
}
}
public async Task<object> Foo(dynamic input)
{
// Receives the callback function that will be used:
Callback = (Func<object, Task<object>>)input.callback;
// Starts a new thread that will call back periodically:
(new Thread(Bar)).Start();
return new object { };
}
}
The only solution I could come up with was to register a timer with a long interval to call an empty function just to keep the scheduler busy and avoid getting the event loop empty so that the process keeps running forever.
Is there any way to do this better than I did? I.e., keep the process running without having to use this kind of "hack"?
The simplest, least intrusive solution
I honestly think my approach is the least intrusive one:
setInterval(() => {}, 1 << 30);
This will set a harmless interval that will fire approximately once every 12 days, effectively doing nothing, but keeping the process running.
Originally, my solution used Number.POSITIVE_INFINITY as the period, so the timer would actually never fire, but this behavior was recently changed by the API and now it doesn't accept anything greater than 2147483647 (i.e., 2 ** 31 - 1). See docs here and here.
Comments on other solutions
For reference, here are the other two answers given so far:
Joe's (deleted since then, but perfectly valid):
require('net').createServer().listen();
Will create a "bogus listener", as he called it. A minor downside is that we'd allocate a port just for that.
Jacob's:
process.stdin.resume();
Or the equivalent:
process.stdin.on("data", () => {});
Puts stdin into "old" mode, a deprecated feature that is still present in Node.js for compatibility with scripts written prior to Node.js v0.10 (reference).
I'd advise against it. Not only it's deprecated, it also unnecessarily messes with stdin.
Use "old" Streams mode to listen for a standard input that will never come:
// Start reading from stdin so we don't exit.
process.stdin.resume();
Here is IFFE based on the accepted answer:
(function keepProcessRunning() {
setTimeout(keepProcessRunning, 1 << 30);
})();
and here is conditional exit:
let flag = true;
(function keepProcessRunning() {
setTimeout(() => flag && keepProcessRunning(), 1000);
})();
You could use a setTimeout(function() {""},1000000000000000000); command to keep your script alive without overload.
spin up a nice repl, node would do the same if it didn't receive an exit code anyway:
import("repl").then(repl=>
repl.start({prompt:"\x1b[31m"+process.versions.node+": \x1b[0m"}));
I'll throw another hack into the mix. Here's how to do it with Promise:
new Promise(_ => null);
Throw that at the bottom of your .js file and it should run forever.

Run NodeJS event loop / wait for child process to finish

I first tried a general description of the problem, then some more detail why the usual approaches don't work. If you would like to read these abstracted explanations go on. In the end I explain the greater problem and the specific application, so if you would rather read that, jump to "Actual application".
I am using a node.js child-process to do some computationally intensive work. The parent process does it's work but at some point in the execution it reaches a point where it must have the information from the child process before continuing. Therefore, I am looking for a way to wait for the child-process to finish.
My current setup looks somewhat like this:
importantDataCalculator = fork("./runtime");
importantDataCalculator.on("message", function (msg) {
if (msg.type === "result") {
importantData = msg.data;
} else if (msg.type === "error") {
importantData = null;
} else {
throw new Error("Unknown message from dataGenerator!");
}
});
and somewhere else
function getImportantData() {
while (importantData === undefined) {
// wait for the importantDataGenerator to finish
}
if (importantData === null) {
throw new Error("Data could not be generated.");
} else {
// we should have a proper data now
return importantData;
}
}
So when the parent process starts, it executes the first bit of code, spawning a child process to calculate the data and goes on doing it's own bit of work. When the time comes that it needs the result from the child process to continue it calls getImportantData(). So the idea is that getImportantData() blocks until the data is calculated.
However, the way I used doesn't work. I think this is due to me preventing the event loop from executing by using the while-loop. And since the Event-Loop does not execute no message from the child-process can be received and thus the condition of the while-loop can not change, making it an infinite loop.
Of course, I don't really want to use this kind of while-loop. What I would rather do is tell node.js "execute one iteration of the event loop, then get back to me". I would do this repeatedly, until the data I need was received and then continue the execution where I left of by returning from the getter.
I realize that his poses the danger of reentering the same function several times, but the module I want to use this in does almost nothing on the event loop except for waiting for this message from the child process and sending out other messages reporting it's progress, so that shouldn't be a problem.
Is there way to execute just one iteration of the event loop in Node.js? Or is there another way to achieve something similar? Or is there a completely different approach to achieve what I'm trying to do here?
The only solution I could think of so far is to change the calculation in such a way that I introduce yet another process. In this scenario, there would be the process calculating the important data, a process calculating the bits of data for which the important data is not needed and a parent process for these two, which just waits for data from the two child-processes and combines the pieces when they arrive. Since it does not have to do any computationally intensive work itself, it can just wait for events from the event loop (=messages) and react to them, forwarding the combined data as necessary and storing pieces of data that cannot be combined yet.
However this introduces yet another process and even more inter-process communication, which introduces more overhead, which I would like to avoid.
Edit
I see that more detail is needed.
The parent process (let's call it process 1) is itself a process spawned by another process (process 0) to do some computationally intensive work. Actually, it just executes some code over which I don't have control, so I cannot make it work asynchronously. What I can do (and have done) is make the code that is executed regularly call a function to report it's progress and provided partial results. This progress report is then send back to the original process via IPC.
But in rare cases the partial results are not correct, so they have to be modified. To do so I need some data I can calculate independently from the normal calculation. However, this calculation could take several seconds; thus, I start another process (process 2) to do this calculation and provide the result to process 1, via an IPC message. Now process 1 and 2 are happily calculating there stuff, and hopefully the corrective data calculated by process 2 is finished before process 1 needs it. But sometimes one of the early results of process 1 needs to be corrected and in that case I have to wait for process 2 to finish its calculation. Blocking the event loop of process 1 is theoretically not a problem, since the main process (process 0) would not be be affected by it. The only problem is, that by preventing the further execution of code in process 1 I am also blocking the event loop, which prevents it from ever receiving the result from process 2.
So I need to somehow pause the further execution of code in process 1 without blocking the event loop. I was hoping that there was a call like process.runEventLoopIteration that executes an iteration of the event loop and then returns.
I would then change the code like this:
function getImportantData() {
while (importantData === undefined) {
process.runEventLoopIteration();
}
if (importantData === null) {
throw new Error("Data could not be generated.");
} else {
// we should have a proper data now
return importantData;
}
}
thus executing the event loop until I have received the necessary data but NOT continuing the execution of the code that called getImportantData().
Basically what I'm doing in process 1 is this:
function callback(partialDataMessage) {
if (partialDataMessage.needsCorrection) {
getImportantData();
// use data to correct message
process.send(correctedMessage); // send corrected result to main process
} else {
process.send(partialDataMessage); // send unmodified result to main process
}
}
function executeCode(code) {
run(code, callback); // the callback will be called from time to time when the code produces new data
// this call is synchronous, run is blocking until the calculation is finished
// so if we reach this point we are done
// the only way to pause the execution of the code is to NOT return from the callback
}
Actual application/implementation/problem
I need this behaviour for the following application. If you have a better approach to achieve this feel free to propose it.
I want to execute arbitrary code and be notified about what variables it changes, what functions are called, what exceptions occur etc. I also need the location of these events in the code to be able to display the gathered information in the UI next to the original code.
To achieve this, I instrument the code and insert callbacks into it. I then execute the code, wrapping the execution in a try-catch block. Whenever the callback is called with some data about the execution (e.g. a variable change) I send a message to the main process telling it about the change. This way, the user is notified about the execution of the code, while it is running. The location information for the events generated by these callbacks is added to the callback call during the instrumentation, so that is not a problem.
The problem appears, when an exception occurs. I also want to notify the user about exceptions in the tested code. Therefore, I wrapped the execution of the code in a try-catch and any exceptions that get out of the execution are caught and send to the user interface. But the location of the errors is not correct. An Error object created by node.js has a complete call stack so it knows where it occurred. But this location if relative to the instrumented code, so I cannot use this location information as is, to display the error next to the original code. I need to transform this location in the instrumented code into a location in the original code. To do so, after instrumenting the code, I calculate a source map to map locations in the instrumented code to locations in the original code. However, this calculation might take several seconds. So, I figured, I would start a child process to calculate the source map, while the execution of the instrumented code is already started. Then, when an exception occurs, I check whether the source map has already been calculated, and if it hasn't I wait for the calculation to finish to be able to correct the location.
Since the code to be executed and watched can be completely arbitrary I cannot trivially rewrite it to be asynchronous. I only know that it calls the provided callback, because I instrumented the code to do so. I also cannot just store the message and return to continue the execution of the code, checking back during the next call whether the source map has been finished, because continuing the execution of the code would also block the event-loop, preventing the calculated source map from ever being received in the execution process. Or if it is received, then only after the code to execute has completely finished, which could be quite late or never (if the code to execute contains an infinite loop). But before I receive the sourceMap I cannot send further updates about the execution state. Combined, this means I would only be able to send the corrected progress messages after the code to execute has finished (which might be never) which completely defeats the purpose of the program (to enable the programmer to watch what the code does, while it executes).
Temporarily surrendering control to the event loop would solve this problem. However, that does not seem to be possible. The other idea I have is to introduce a third process which controls both the execution process and the sourceMapGeneration process. It receives progress messages from the execution process and if any of the messages needs correction it waits for the sourceMapGeneration process. Since the processes are independent, the controlling process can store the received messages and wait for the sourceMapGeneration process while the execution process continues executing, and as soon as it receives the source map, it corrects the messages and sends all of them off.
However, this would not only require yet another process (overhead) it also means I have to transfer the code once more between processes and since the code can have thousands of line that in itself can take some time, so I would like to move it around as little as possible.
I hope this explains, why I cannot and didn't use the usual "asynchronous callback" approach.
Adding a third ( :) ) solution to your problem after you clarified what behavior you seek I suggest using Fibers.
Fibers let you do co-routines in nodejs. Coroutines are functions that allow multiple entry/exit points. This means you will be able to yield control and resume it as you please.
Here is a sleep function from the official documentation that does exactly that, sleep for a given amount of time and perform actions.
function sleep(ms) {
var fiber = Fiber.current;
setTimeout(function() {
fiber.run();
}, ms);
Fiber.yield();
}
Fiber(function() {
console.log('wait... ' + new Date);
sleep(1000);
console.log('ok... ' + new Date);
}).run();
console.log('back in main');
You can place the code that does the waiting for the resource in a function, causing it to yield and then run again when the task is done.
For example, adapting your example from the question:
var pausedExecution, importantData;
function getImportantData() {
while (importantData === undefined) {
pausedExecution = Fiber.current;
Fiber.yield();
pausedExecution = undefined;
}
if (importantData === null) {
throw new Error("Data could not be generated.");
} else {
// we should have proper data now
return importantData;
}
}
function callback(partialDataMessage) {
if (partialDataMessage.needsCorrection) {
var theData = getImportantData();
// use data to correct message
process.send(correctedMessage); // send corrected result to main process
} else {
process.send(partialDataMessage); // send unmodified result to main process
}
}
function executeCode(code) {
// setup child process to calculate the data
importantDataCalculator = fork("./runtime");
importantDataCalculator.on("message", function (msg) {
if (msg.type === "result") {
importantData = msg.data;
} else if (msg.type === "error") {
importantData = null;
} else {
throw new Error("Unknown message from dataGenerator!");
}
if (pausedExecution) {
// execution is waiting for the data
pausedExecution.run();
}
});
// wrap the execution of the code in a Fiber, so it can be paused
Fiber(function () {
runCodeWithCallback(code, callback); // the callback will be called from time to time when the code produces new data
// this callback is synchronous and blocking,
// but it will yield control to the event loop if it has to wait for the child-process to finish
}).run();
}
Good luck! I always say it is better to solve one problem in 3 ways than solving 3 problems the same way. I'm glad we were able to work out something that worked for you. Admittingly, this was a pretty interesting question.
The rule of asynchronous programming is, once you've entered asynchronous code, you must continue to use asynchronous code. While you can continue to call the function over and over via setImmediate or something of the sort, you still have the issue that you're trying to return from an asynchronous process.
Without knowing more about your program, I can't tell you exactly how you should structure it, but by and large the way to "return" data from a process that involves asynchronous code is to pass in a callback; perhaps this will put you on the right track:
function getImportantData(callback) {
importantDataCalculator = fork("./runtime");
importantDataCalculator.on("message", function (msg) {
if (msg.type === "result") {
callback(null, msg.data);
} else if (msg.type === "error") {
callback(new Error("Data could not be generated."));
} else {
callback(new Error("Unknown message from sourceMapGenerator!"));
}
});
}
You would then use this function like this:
getImportantData(function(error, data) {
if (error) {
// handle the error somehow
} else {
// `data` is the data from the forked process
}
});
I talk about this in a bit more detail in one of my screencasts, Thinking Asynchronously.
What you are running into is a very common scenario that skilled programmers who are starting with nodejs often struggle with.
You're correct. You can't do this the way you are attempting (loop).
The main process in node.js is single threaded and you are blocking the event loop.
The simplest way to resolve this is something like:
function getImportantData() {
if(importantData === undefined){ // not set yet
setImmediate(getImportantData); // try again on the next event loop cycle
return; //stop this attempt
}
if (importantData === null) {
throw new Error("Data could not be generated.");
} else {
// we should have a proper data now
return importantData;
}
}
What we are doing, is that the function is re-attempting to process the data on the next iteration of the event loop using setImmediate.
This introduces a new problem though, your function returns a value. Since it will not be ready, the value you are returning is undefined. So you have to code reactively. You need to tell your code what to do when the data arrives.
This is typically done in node with a callback
function getImportantData(err,whenDone) {
if(importantData === undefined){ // not set yet
setImmediate(getImportantData.bind(null,whenDone)); // try again on the next event loop cycle
return; //stop this attempt
}
if (importantData === null) {
err("Data could not be generated.");
} else {
// we should have a proper data now
whenDone(importantData);
}
}
This can be used in the following way
getImportantData(function(err){
throw new Error(err); // error handling function callback
}, function(data){ //this is whenDone in our case
//perform actions on the important data
})
Your question (updated) is very interesting, it appears to be closely related to a problem I had with asynchronously catching exceptions. (Also Brandon and Ihad an interesting discussion with me about it! It's a small world)
See this question on how to catch exceptions asynchronously. The key concept is that you can use (assuming nodejs 0.8+) nodejs domains to constrain the scope of an exception.
This will allow you to easily get the location of the exception since you can surround asynchronous blocks with atry/catch. I think this should solve the bigger issue here.
You can find the relevant code in the linked question. The usage is something like:
atry(function() {
setTimeout(function(){
throw "something";
},1000);
}).catch(function(err){
console.log("caught "+err);
});
Since you have access to the scope of atry you can get the stack trace there which would let you skip the more complicated source-map usage.
Good luck!

Resources