I have a huge parsing function, if the file is correct, it work well, but I can t handle error correctly.
function parse (pathname, callback){
//Some variables
fs.open(pathname, 'r', function(err, fd){
if (err){console.log('Error Opening the file'); callback(-1);}
console.log('Begin the parsing');
//Do the parsing
But if I give a invalid pathname, I get the message of Error, and the function continue until a fatal error when reading.
I thought callback was ending the function, but it seem I m wrong.
I could do something like:
function parse (pathname, callback){
//Some variables
fs.open(pathname, 'r', function(err, fd){
if (err){console.log('Error Opening the file'); callback(-1);}
else{
console.log('Begin the parsing');
//Do the parsing
But there s a lot of error handling in it, and the function is quite huge.
In other s code I usually see
if (err){throw err;}
But I never suceed in doing anything, even simple, with event, so I d like to avoid this too, and if I don t handle it, it end up closing the app, wich I don t want too.
Is there a neat way to let me handle the error in another way?
You could make the function parse return which will interrupt the function execution.
if (err) {
console.log('Error opening the file');
callback(-1);
return; // Alternatively return false or anything you want
}
Calling callback(-1) does not end the function since it is a simple function call just like console.log() or any other function.
Related
We can stub any function or class like this,
class ErrorStub{
constructor(message){
// do whatever with 'message'
}
}
Error = ErrorStub
new Error('This will go to ErrorStub now')
Similar to this, is there any way we can intercept a 'throw' statement. So that whatever exception is thrown across whole website, can be handled in one place?
Wouldn't this satisfy your needs? You would need to listen to the error event, handle it the way you want and return false
function interceptError(exception) {
// Here you can write code which intercepts before
// the error gets triggered and printed in the console
alert(`Exception occured: ${exception.message}`)
}
window.addEventListener("error", function (e) {
interceptError(e);
return false;
})
throw new Error('Test exception');
I am using writeFileSync function to write a file locally, the file does get written, however, the callback function is never called.
I did some googling, some other post are having the issue that it's either 1) passing the content went wrong or 2) having two write function at the same time.
My problem is that there are some other places in my code that is using the writeFileSync, but they are on different routes (not sure if this is the right terminology, localhost:port#/differentroutes <- something like this). I am testing only on my own route so those write functions shouldn't even be called.
Here is my code:
if(!fs.existsSync(dir)){
fs.mkdirSync(dir)
}
//content is just a string var I swear it's just a string
fs.writeFileSync('./pages/SubmissionProcess.html',content,function(err){
if(err){
throw err
}else {
console.log("YES")
}
})
I never see this "YES" nor error in my console even tho the file is already written....
Write file sync doesn't take a callback :D
Take a look at the documentation :
https://nodejs.org/api/fs.html#fs_fs_writefilesync_file_data_options
The parameters are (path, data, options)
If you want to check if the file actually wrote, you can read file sync after writing it or check the last time the file was updated. Otherwise, you should try using the async approach.
All of the synchronous methods throw rather than passing an error to a callback.
try {
fs.writeFileSync('./pages/SubmissionProcess.html', content);
console.log('YES');
} catch (e) {
console.error(e);
}
I have a js file called example.js which has a line as follows:
gridOptions.api.setRowData(createRowData());
Then there's another file data.js which has the createRowData() function that should return ROW_DATA. It is as follows:
function createRowData() {
jQuery.getJSON('/file.txt',function(ROW_DATA){
return ROW_DATA;
});
}
But, whenever this createRowData() function is called from example.js file, it does not go inside the jQuery block and simply comes to the last curly bracket. Can anyone please tell me what is going wrong here??
I believe that you're not getting the value because getJSON is asynchronous as others have said. createRowData is retrieving the value at a later time rather than when it's called.
Here is one way to get the data with promises. I commented what's going on below:
function createRowData() {
//return a new promise
return new Promise(function(resolve, reject){
jQuery.getJSON('/file.txt',function(ROW_DATA){
//on reject, send an error
if (ROW_DATA === null) reject("Error fetching data");
//on resolve, send the row data
return resolve(ROW_DATA);
});
});
}
//use then to describe what happens after the ajax request is done
gridOptions.api.setRowData(createRowData()).then(function(rowdata){
return rowdata; //log data or error
})
Edit: to do a synchronous ajax request, you may be able to do something like this, referring to this SO question.
function createRowData() {
$.ajax({
url: "/file.txt'",
async: false,
success: function(rowdata){
return rowdata
}
})
}
To read some data to a variable like you mentioned, nodejs may help because it can handle reading input/output, and probably to a variable as well.:
You get JSON from the file, pass the result to the callback function, and then return it. Return it where??
As I said, your anonymous function is a callback one.
Program says: When you are done reading from the file, call this function, OK?.
While you do that, I am doing something else.
And that is what it does. The program, would go on, until the file is read, when your callback anonymous function would be called.
You can do sth like this.
createRowData(gridOptions.api);
// add code here if you want this code to execute even before you get the response
function createRowData(api) {
jQuery.getJSON('/file.txt',function(ROW_DATA,api){
api.setRowData(ROW_DATA);
//Whatever else you want to do. In case you want this to be done only
//after the values have been read
});
}
If you want to wait, for the file to be read, just, dont do anything after the function, but put it inside the callback function.
I'm used to throwing an instance of some error class and having them be caught somewhere down the line in the app, to account for user error.
An example might be validating the username:
function validateUsername (username) {
if (!/^[a-z0-9_-]{3,15}$/.test(username)) {
throw new ValidationError('Please enter 3-15 letters, digits, -, and/or _.');
}
}
$('#username').blur(function () {
try {
validateUsername($(this).val());
} catch (x) {
$('<p></p>').addClass('error').text(x).insertAfter(this);
}
});
But now I'm realizing that I can't use these same practices for asynchronous calls. For example:
function checkUsernameAvailability (username) {
$.get('/users/' + username).done(function () {
// Done = user returned; therefore, username is unavailable
// But I can't catch this error without resorting to something gross
// like window.onerror
throw new ValidationError('The username you entered is already in use.');
});
}
I could make checkUsernameAvailability accept a callback and/or return a promise and have it execute said callback with the availability of the username.
$('#username').blur(function () {
checkUsernameAvailability(username, function (available) {
!available && alert('The username you entered is already in use.');
});
});
But part of what makes exceptions so powerful is that they can bubble up the stack until they get caught, whereas if I had another function that called another function that called checkUsernameAvailability, I'd need to pass the result of this callback manually all the way until I get to the place where I want to handle it.
What are some of the alternative methods for passing errors up the stack? I can think of some of these, but none of them are as clean as native exceptions:
Passing a flag, or the ValidationError instance, to a callback (Node.js approach could work too, passing an error or null as the first argument, and the data as the second); but then, if I don't want to handle it at that point in the stack, I need to pass the error up manually
Or passing 2 callbacks to the checkUsernameAvailability function, a success callback and an error callback; this seems to have the same drawbacks as the previous point
Triggering a "ValidationError" event so I can listen anywhere, but make sure to return false; in the handler so it doesn't execute higher in the stack; however, this pollutes the event namespace and could make it unclear as to which event listener will be executed first; plus, it's difficult to trace an event to its origin using the console
in principal it is like this
function Exception (errcode) {
this.code = errcode;
}
...
try {
...
throw new Exception('alpha');
...
} catch (e) {
if (e.code === {something}) {
}
}
If it helps, I recently took the first release of the Rogue game written for UNIX in C and rewrote it for javascript to work in a browser. I used a technic called continuation to be able to wait for key entry by the user because in javascript the are no interrupts.
So I would have a piece of code like this:
void function f() {
// ... first part
ch = getchar();
// ... second part
}
that would be transformed in
function f() {
// ... first part
var ch = getchar(f_cont1);
return;
// the execution stops here
function f_cont1 () {
// ... second part
}
}
the continuation is then stored to be reuse on a keypressed event. With closures everything would be restarted where it stoped.
I am trying to load some content using require.js. If the content doesn't exist I'd like to catch the error and notify the user.
In firebug I can see two errors:
"NetworkError: 404 Not Found
...and then a few seconds later:
var e = new Error(msg + '\nhttp://requirejs.org/docs/errors.html#
Load timeout for modules: modules/messages/messages
http://requirejs.org/docs/errors.html#timeout
My code resembles:
require([path], function(content){
//need to catch errors as this will not be called;
});
How would one bind to requirejs events? Any idea?
It is also possible to use errbacks to have customized error handling appropriate to the specific use of require. Errbacks are documented here http://requirejs.org/docs/api.html#errbacks. Basically, you can add to require a function to be called if the load fails. It comes right after the function to be called if the load is successful.
Chin's case could be handled as:
require([path], function(content){
//need to catch errors as this will not be called;
}, function (err) {
//display error to user
});
Here's an example that tries loading from multiple places:
require([mode_path], onload, function (err) {
if (mode_path.indexOf("/") !== -1)
// It is an actual path so don't try any further loading
throw new Error("can't load mode " + mode_path);
var path = "./modes/" + mode_path + "/" + mode_path;
require([path], onload,
function (err) {
require([path + "_mode"], onload);
});
});
In this example onload would be the function called once the required code loads, and mode_path is a string identifying the mode. What you see there is code attempting to load a mode module for an editor from 3 different locations. If mode_path is foo, it will try to load foo, then ./modes/foo/foo and then ./modes/foo/foo_mode.
The example at requirejs.org shows how one might handle a case where they want to try multiple locations for a resource they want to make available with a well-known identifier. Presumably the entire code-base in that example requires jQuery by requiring "jquery". Whatever location jQuery happens to be located at, it becomes available to the whole code-base as "jquery".
My example does not care about making the mode known to the entire code-base through a well-known identifier because in this specific case there's no good reason to do so. The onload function stores the module it gets into a variable and the rest of the code base gets it by calling a getMode() method.
set the requirejs onError function:
requirejs.onError = function (err) {
if (err.requireType === 'timeout') {
// tell user
alert("error: "+err);
} else {
throw err;
}
};
If you want to setup an event you could bind to and trigger a global object. Such as:
$("body").bind("moduleFail",function(){
alert("Handling Event")
});
requirejs.onError = function (err) {
if (err.requireType === 'timeout') {
$("body").trigger({type:"moduleFail",err:err})
} else {
throw err;
}
};
require(["foo"],function(foo){
alert("loaded foo" + foo)
})
Did you try to override the requirejs.onError like shown here?
It worked for me after setting catchError as true like this:
require.config({catchError:true});
before calling any define() or require() functions.
You can use the requirejs.onError function as :
requirejs.onError = function (err) {
if (err) {
//Reload
}
else {
throw err;
}
};
You can also use err.requireType to catch specific errors like timeouts