Throw statement in JavaScript gives "undefined undefined" output - javascript

Anytime I try using the throw statement in a try/catch command.
It gives me an output of undefined undefined.
Please how can I make it work.
Here is the code I used
try {
let a = prompt("Answer");
if (a == 10) {
throw "right";
} else {
throw "wrong"
}
} catch (i) {
alert(i.message);
}

You have multiple errors:
You have to convert the result to a number before the comparison, you can use the Number function.
You have to show the error and not only its message property since you are throwing a string and not an object.
try {
const a = Number(prompt('Answer'));
if (a === 10) {
throw 'right';
} else {
throw 'wrong';
}
} catch (e) {
alert(e);
}

Related

Unclear Behaviour With `throw`and String Concatenation

I have this code:
const func = () => {
throw new Error('hey') + 'boo'
return 'OK'
}
try {
const val = func()
console.log(val)
} catch (error) {
console.log(error)
}
When launched the result is a console line:
"Error: heyboo"
But this is not clear reading the code.
What's the reason for this?
It's because you're doing new Error('hey') + 'boo' and throwing that (which may be surprising). Here's what the code is doing:
Creates the error object
Does + on the error object and 'boo', which converts the error object to string ("Error: hey") and appends "boo" to it
Throws the resulting "Error: heyboo" string
...which you then catch and display.
JavaScript is slightly unusual compared to other languages in that it lets you throw any value, including a string. You aren't restricted to throwing Error objects.
This code does the same thing, hopefully making it a bit clearer by breaking things into steps:
const func = () => {
// Create error
const error = new Error("hey");
// Append `"boo"` to it to get a string
const str = error + "boo";
// Throw the string
throw str;
// This is never reached
return "OK";
};
try {
const val = func();
console.log(val);
} catch (error) {
console.log(error);
}

how to make if there is no file it will do nothing

hey so I'm trying to const some JSON
const cidc = require('./cid/cid.json')
const dc = require('./details/cid.json')
const lc = require('./lik/cid.json')
if(!cidc){
return
}else{
fs.unlinkSync('./src/main/setting/cid/cid.json')
} if(!dc) {
return
}else {
fs.unlinkSync('./src/main/setting/details/cid.json')
} if (!lc){
return
}else {
fs.unlinkSync('./src/main/setting/lik/cid.json')
}
so I'm trying to delete the dc file and it error
how can I make if there is no such file named that it will do nothing (aka return nothing)
and if there is a file named that it will const it to a variable
Since require throws an error of Error: Cannot find module ... and you don't catch those errors, your script will fail.
You could define a new require-function where you catch the error and return undefined:
function safeRequire(path) {
try {
return require(path);
} catch(err) {
return undefined;
}
}
Then use this function in your script:
const cidc = safeRequire('./cid/cid.json')
const dc = safeRequire('./details/cid.json')
const lc = safeRequire('./lik/cid.json')
// rest of your code
Also you can simplify your if/else conditions by inverting the condition:
if (cidc) {
fs.unlinkSync('./src/main/setting/cid/cid.json')
}
if (dc) {
fs.unlinkSync('./src/main/setting/details/cid.json')
}
if (lc){
fs.unlinkSync('./src/main/setting/lik/cid.json')
}
Alternatively you don't even need to use require at all, just check if the files exist using e.g. fs.access(...).
You could directly use unlink with try catch without any requires
function unlink(filePath) {
try {
fs.unlinkSync(filePath);
} catch (e) {
//ignore
}
}
unlink('./src/main/setting/cid/cid.json')
unlink('./src/main/setting/details/cid.json')
unlink('./src/main/setting/lik/cid.json')

Declaring Custom Exceptions to use with Firestore Callable Functions and VueJS

This far, I tried
A
class MyException extends Error {
constructor(message, code) {
super(message);
this.code = code;
}
}
exports.MyException = MyException;
VueJS says "exports is not defined"
If I simply did
B
exports.MyException = () => {}
then Firebase says MyException is not a constructor. When I
throw new MyException()
Actually, once the exception is passed through callable functions, would it still be an instanceOf?
Should I just go with
C
try {
let d = await db.collection('x').document('y')
if (!d.exists) {
let e = new Error('Document Does not Exist')
e.code = 'ERR_NO_DOCUMENT'
throw e
}
else {
return d.data()
}
}
Is C a good practice?
As explained in the documentation for Callable Cloud Functions:
To ensure the client gets useful error details, return errors from a
callable by throwing (or returning a Promise rejected with) an
instance of functions.https.HttpsError.
So doing
try {
let d = await db.collection('x').document('y')
if (!d.exists) {
let e = new Error('Document Does not Exist')
e.code = 'ERR_NO_DOCUMENT'
throw e
}
else {
return d.data()
}
}
will not work.
You need to do, in your Callable Cloud Function, something like:
try {
let d = await db.collection('x').document('y')
if (!d.exists) {
let e = new Error('Document Does not Exist')
e.code = 'ERR_NO_DOCUMENT'
throw e
}
else {
return d.data()
}
} catch (error) {
throw new functions.https.HttpsError('internal', error.message);
}

prompt validation if null not working inside funcion/while/try javascript

as said on title, validating the prompt if is null (inpname variable) inside the func/while/try wont work. output = {}
meanwhile the testing i did outside works fine.
check the code below please. what did i do wrong?
//works
let test = prompt("testing","aasdasd");
if (test === null) {
console.log("cancel");
}
else {
console.log("ok");
}
let inpname;
//do not work
let func = () => {
while (true) {
try {
inpname = prompt("name ", "name here");
if (inpname.length > 10 || inpname.length <= 3) {
throw "Your name must be at least 10 characters long, but not less than 4";
}
else if ( inpname != inpname.match(/^[a-zA-Z]+$/)) {
throw "A-Z characters accepted only!";
}
//problem here!
else if (inpname === null) {
throw "cant cancel";
}
else {
console.log("success");
break
}
}
catch (err) {
console.log(err);
break
}
}
}
func();
The console outputting {} instead of the exception seems to be a bug in Stack-snippets. You would get more correct output using console.error.
That being said, the issue you're seeing is in part caused because you're not checking that impname is null before you attempt to dereference it.
Changing the ordering of your error checking would solve the problem (Although stack-snippets is still not going to report exceptions as they happen, which is not the behavior you get in a browser)
let func = () => {
while(true) {
var inpname = prompt("name ", "name here");
try {
if (inpname === null) {
throw "cant cancel";
}
if (inpname.length > 10 || inpname.length <= 3) {
throw "Your name must be at least 10 characters long, but not less than 4";
}
if (inpname != inpname.match(/^[a-zA-Z]+$/)) {
throw "A-Z characters accepted only!";
}
return inpname;
} catch(err) {
console.error(err);
}
}
}
func();
Note that you might want to avoid disallowing use of the "cancel" button. If the user doesn't want to provide the requested info, simply exit the app with an appropriate message

Why is the error not thrown in this code?

This is my code (Javascript):
function getNumbers(){
var numberString = document.getElementById("numbers").value;
var actualNumbers = [];
var flowIndex = 0;
for(let i = 0; i < numberString.length; i++){
if(numberString.charAt(i) != " " && numberString.charAt(i) != "\," && numberString.charAt(i) != "\t"){
actualNumbers[flowIndex] = parseInt(numberString.charAt(i));
flowIndex++;
}
else continue;
}
return actualNumbers;
}
function division(){
try{
var answer = getNumbers()[0] / getNumbers()[1];
if(getNumbers()[1] == 0)
throw "bad";
}
catch(error){
throw error.description + "Division by zero error";
}
finally{
return answer;
}
}
I have a function getNumbers() which returns an array, with array[0] = 1 and array[1] = 0. Now, I want to throw an exception "bad" when array[1] == 0. But, neither the try exception nor the catch exception is being thrown, but the finally clause is working. What is the problem?
NOTE: On division by zero, no exception is being thrown, instead answer is coming out to be Infinity. getNumbers() is working properly.
The exception is getting thrown, but then you're suppressing the exception by doing this:
finally {
return answer;
}
The finally clause gets final say. If you return from it, that suppresses the exception and makes the function complete normally.
One way to fix it is to remove the finally clause and put the return answer; inside your try.
Just FWIW, some other notes as comments:
function getNumbers(){
var numberString = document.getElementById("numbers").value;
var actualNumbers = [];
var flowIndex = 0;
// You might consider splitting the string into an array of one-character strings so you
// aren't constantly calling a method (`charAt`), like this:
// `var chars = numberString.split("");`
// Then index into `chars`
// N.B. `let` is an ES2015 (ES6) feature not all JavaScript engines have as it's new;
// the rest of your code is using the older `var`
// --v
for (let i = 0; i < numberString.length; i++){
// No need to escape the comma --------------------------------v
if(numberString.charAt(i) != " " && numberString.charAt(i) != "\," && numberString.charAt(i) != "\t"){
actualNumbers[flowIndex] = parseInt(numberString.charAt(i));
flowIndex++;
}
// No need for the `else continue;` at all
else continue;
// In the above, you regularly call `charAt` four times when once would have been sufficient.
// You might also consider a `switch`
}
return actualNumbers;
}
function division(){
try{
// Rather than calling `getNumbers` three separate times, call it once and remember its return value
// doing the calculation should be AFTER checking [1] for 0, not before
var answer = getNumbers()[0] / getNumbers()[1];
if(getNumbers()[1] == 0)
throw "bad"; // Recommend using Error, e.g.: `throw new Error("bad")`
// Move the `return answer;` here
}
catch(error){
// You've thrown a string, it doesn't have a `description` property
// Separately: Why throw something above, just to catch it here and throw something else?
throw error.description + "Division by zero error";
}
// Remove the finally
finally{
return answer;
}
}
Again just FWIW, I'd probably put responsibility for getting the value from the input in division (or even in the thing calling division) rather than in getNumbers, and use /\d/.test(...) to test if a character is a digit, since there are lots of non-digits that aren't " ", ",", or "\t". And once we know they're digits, we can use +ch instead of parseInt to convert them (but with this input, it's just a style choice [well, there's a performance implication, but 99.99% of the time, that doesn't matter]).
So perhaps:
function getNumbers(str) {
var numbers = [];
str.split("").forEach(function(ch) {
if (/\d/.test(ch)) {
numbers.push(+ch);
}
});
return numbers;
}
function division() {
var numbers = getNumbers(document.getElementById("numbers").value);
if (numbers[1] == 0) {
throw new Error("Division by zero error");
}
return numbers[0] / numbers[1];
}
Or with an alternate getNumbers that is more concise, but makes more loops through the input (which usually doesn't matter):
function getNumbers(str) {
return str.split("")
.filter(function(ch) { return /\d/.test(ch); })
.map(function(ch) { return +ch; });
}
function division() {
var numbers = getNumbers(document.getElementById("numbers").value);
if (numbers[1] == 0) {
throw new Error("Division by zero error");
}
return numbers[0] / numbers[1];
}

Categories