By default, the Haxe PHP target sets the error reporting level to the maximum setting and overrides the default error handler:
error_reporting(E_ALL & ~E_STRICT);
set_error_handler('_hx_error_handler', E_ALL);
set_exception_handler('_hx_exception_handler');
I'm writing a PHP library that is intended to be used within a larger codebase and overriding the error handling like this is seriously problematic. I'm aware that I can rollback the error handling settings but that means resetting the error handler every time the codebase is called. This forces a fairly functional style and makes async much more complicated. I could comment out those lines, but I would prefer to not rely on monkey patching.
Is there a compiler flag I can pass to specify the error reporting level? Can I somehow prevent the error handling overrides from leaking into code that uses my library?
Related
I have a random Runtime Error 216 that appears on application close.
I have debugged as far as I can and the error is thrown in SysUtils.FinalizeUnits.
I have gone over the code and ensure all created objects are freed.
The number on the runtime error, 0040054A, is not present in the mapfile. Do you know what this means?
Can anyone tell me how to find out what is throwing the error?
This is VERY OLD Delphi problem - wrong exception handling in unit initialization/finalization process.
The problem easy to reproduce - just make any program error/exception (division by zero for instance) in initialization block of any unit. The exception will be created correctly. But then, before the exception rise, the unit finalization process destroy the exception object. And thus, when the exception object accessed, the "runtime error 216" occured.
I'd suspect a memory leak (all Runtime Errors 216 I've encountered so far were) and use a profiler (visual inspection is never as good as a tool). Since you're using Delphi XE, you should give AQTime a try (it's included), see also
Delphi - Check if memory is being released "on time"
Kind regards, Frank
Since runtime error 216 is an access violation, this may indicate that you're attempting to use something that you've already freed.
Addresses in the map file are based at 0, but that's not where your EXE file gets loaded into memory. Your EXE gets loaded at its preferred base address, which is usually $400000. Subtract that from the address you have. The address you're looking for in the map file is $0000054a.
There was a similar question, Read:
How to debug a crash that only occurs on application shutdown? (Delphi)
Consider using Memory profiler, this may help identifying live objects after app was terminitated.
I suggest you try the FastMM Full Debug Mode, and either statically link that into your app, or use it as a package (if your app uses packages).
You can use the method I used to fix mine.
I commented out the main program, and added code back until it failed.
Turns out that it did not want me to call couninitialize at all. Did not throw an error at the time, but failed after program termination with a 216. Removing the offending statement fixed it.
Since this was maybe 6 statements before end. statement, I don't imagine it will matter.
This method is easy if you are consistent about using // for comments. I moved IO statements that needed curly brackets to a procedure.
On Microsoft's oficial web site it is mentioned that, this issue can occur if your computer is infected with a SubSeven Trojan virus.
Antivirus software and windows registry cleaner should help.
We have been facing a very strange issue with one of our RPGLE programs that bombs intermittently with the subjected error.
This happens specifically at a line where a write operation is performed to a subfile record format. I have debugged and checked all the values assigned to variables during runtime and could not find absolutely no issues. As per the https://www.ibm.com/support/pages/node/644069 IBM page, I can only assume that this might be related to the parameter definitions of the programs called within the RPG. But I have checked the parameters of each and every prototyped program call and everything seems to be in sync.
Can some one please guide on the direction to go to find out the root cause of this problem?
But I have checked the parameters of each and every prototyped program
call
Assuming you're using prototypes properly, ie. there is one prototype defined in a separate source member and it is /INCLUDE into BOTH the caller and the callee...
Then prototype calls aren't the problem, as long as you're properly handling any *OMIT and *NOPASS parameters.
Look at any old style CALL or CALLB calls and anyplace you're not using prototypes properly...meaning there's a explicit PR coded in both caller & callee.
Note that you it's not just old-style calls made by the program that bombs, it's calls made anywhere down the call chain.
And if the program is repeatedly called with LR=*OFF or without reclaiming resources, then it could be any old style calls up the call chain also.
Lastly, old style calls include any made by CL or CLLE programs.
Good luck!
I am reading Nodejs documentation here https://nodejs.org/api/fs.html#fs_fs_exists_path_callback
And it says fs.exists() and fs.existsAsync() are deprecated.
So my intuition would be that it will throw an error if I am using a newer version of NodeJs.
However, using both NodeJs v4.3.2 and v6, I still see the fs.exists() working. why is it so? does that mean that If I migrate my system from NodeJS v0.10.0, I don't necessarily have to update my dependencies that is invoking such function, and it's backward compatible?
It means that the community behind node.js development are recommending against using this feature now because it has problems and they MAY get rid of it sometime in the future to force people to stop using it.
So my intuition would be that it will throw an error if I am using a newer version of NodeJs.
They have not yet made it throw an error.
However, using both NodeJs v4.3.2 and v6, I still see the fs.exists() working. why is it so?
And, from the title of your question:
but why can I still use it with Node v4 and v6?
Because though they are recommending against using it now, they have not yet removed it.
does that mean that If I migrate my system from NodeJS v0.10.0, I don't necessarily have to update my dependencies that is invoking such function, and it's backward compatible?
No. The community behind node.js is telling you that they are reserving the right to remove those two functions in any future version.
Bottom line: If you want compatibility with future versions, stop using both fs.exists() now.
fs.exists() is also inconsistent with other node.js async APIs in that the callback is has does not follow the typical calling convention of fn(err, data). It does not have the err parameter which makes it an oddball.
You may also want to understand the reason they are problematic to use. A modern operating system is a multi-tasking system and the file system is a shared resource among potentially many processes. That means that if you do:
if (fs.existsSync("somefile")) {
// execute some code when somefile does exist
} else {
// execute some code when somefile does not exist
}
Then, the state of whether somefile exists or not could change between the time you run the fs.existsSync() call and the time you execute the code that assumes it knows whether the file exists or not. That's called a "race condition" and it's considered very bad design because it creates the possibility for extremely hard-to-reproduce bugs that may hit just occasionally (probably the worst kind of bug to try to find).
Note this directly from the node.js doc for fs.exists():
Using fs.exists() to check for the existence of a file before calling
fs.open(), fs.readFile() or fs.writeFile() is not recommended. Doing
so introduces a race condition, since other processes may change the
file's state between the two calls. Instead, user code should
open/read/write the file directly and handle the error raised if the
file does not exist.
If you're using the asynchronous version fs.exists(), then the race condition is even worse because your own node.js code could even change the state of the file because your if/else logic runs.
Depending upon what you are generally trying to do, the non-race-condition substitute is to just attempt to open the file with some sort of exclusive access. If the file exists, you will successfully open it with no race condition. If the file did not exist, you will simply get an error and you can then handle that error. In some other cases, you just attempt to create the file with a mode that will fail if it already exists. Both of these situations use an atomic comparison inside the OS file system code so they do not have "race conditions".
You should fix your code now. If you still don't understand what the recommended fix is, then please post your code that is using fs.exists() and the surrounding code context and we can help you with a better design.
Stability level 0 (or deprecated) in Node.js means it can be removed at anytime, though not necessarily with the immediate next version.
Don't rely on them being backwards-compatible, or even to have similar behaviors across versions even if they are present.
Per the documentation
Stability: 0 - Deprecated This feature is known to be problematic, and changes are planned. Do not rely on it. Use of the feature may cause warnings. Backwards compatibility should not be expected.
In other words, it may drop out or otherwise completely stop working at any point without further notice. It may or may not work if/when you migrate.
For what it's worth, it's not atypical to have deprecated features remain for multiple major versions in other software as well. In the OSS world, I've seen deprecated features that lasted for as long as the project was maintained. Presumably because the maintainer/user base had some use for the deprecated feature because it was good enough for their use case (even if it wasn't as good as it should/could have been, and even when a newer API was developed).
I've been reading articles about methods/best practices to handle errors in node. Besides listening to process.on('uncaughtException'), which considered a bad practice, there is no method to properly handle exceptions troughout the entire application.
All the suggested solutions like using domains, try/catch blocks should be implemented per module (or worse if you use try/catch and not domains, per action).
Am i missing some article/documentation or domains/try-catch blocks are the best available solutions?
The best solution is to rely on asynchronous code.
Asynchronous code show not throw but rather pass the error to the Callback function as the first argument to be handled by the callee. The problem with a lot of modules is that people seem to throw whenever they think it is right to do so and this happens a lot more often than actual syntax exceptions, type exceptions or any exception is thrown by V8. If you don't want your app to crash in production use well-written modules that are truly async and rely on callbacks rather than try/catch and if you really need to rely on a sync module then wrap it around try/catch but there is almost always an async module out there that even though might not perform any I/O passes the error to the callback.
Moreover try/catch does have a performance overhead (albeit tiny) that would put strain on resources if overused (don't wrap every module in try/catch). From experience I suggest if you are developing something that goes into production then try to choose your modules carefully rather than catching their errors later on. process.on('uncaughtException') is a last resort and usually ideal for logging the exceptions.
As an ultimate solution I suggest that you use a process manager. My personal choice is PM2. It will attempt to gracefully restart your code and handles exceptions pretty well.
References:
Try/Catch performance overhead.
Try/Catch performance overhead (recent)
Using PM2 in production
Isaac Schlueter on async code and throw
I am curious how does log4NET can use %L to get the # of line where a log event is fired. Could you give me some elaboration?
Thanks.
It uses a StackTrace as described in the log4net documentation.
Note the caveats in the lognet documentation:
WARNING Generating caller location information is extremely slow. Its use should be avoided unless execution speed is not an issue.
CAUTION
The System.Diagnostics.StackTrace class has this to say about Release builds:
"StackTrace information will be most informative with Debug build configurations. By default, Debug builds include debug symbols, while Release builds do not. The debug symbols contain most of the file, method name, line number, and column information used in constructing StackFrame and StackTrace objects. StackTrace might not report as many method calls as expected, due to code transformations that occur during optimization."
This means that in a Release build the caller information may be incomplete or may not exist at all! Therefore caller location information cannot be relied upon in a Release build.