Can't catch error in try/catch section, decodeAudioData - javascript

I have a broken .mp3 file for testing, I can't catch the error without "app crashed"
The action happens on the backend, then/catch doesn't work with decodeAudioData
const AudioContext = require('web-audio-api').AudioContext;
const context = new AudioContext();
const calcTempo = async (buffer) => {
let audioBuffer;
try {
audioBuffer = await new Promise((resolve, reject) =>
context.decodeAudioData(buffer, resolve, reject)
);
} catch (e) {
console.log(e)
}
}
/usr/src/app/node_modules/av/src/core/stream.js:489
throw new Error("Invalid utf16 sequence.");
^
Error: Invalid utf16 sequence.
at Stream.decodeString (/usr/src/app/node_modules/av/src/core/stream.js:489:23)
at Stream.readString (/usr/src/app/node_modules/av/src/core/stream.js:403:27)
at Class.decodeFrame (/usr/src/app/node_modules/mp3/src/id3.js:117:39)
at Class.readFrame (/usr/src/app/node_modules/mp3/src/id3.js:59:30)
at Class.read (/usr/src/app/node_modules/mp3/src/id3.js:18:33)
at Class.readChunk (/usr/src/app/node_modules/mp3/src/demuxer.js:161:37)
at BufferSource. (/usr/src/app/node_modules/av/src/demuxer.js:49:19)
at BufferSource.EventEmitter.emit (/usr/src/app/node_modules/av/src/core/events.js:64:12)
at BufferSource.loop (/usr/src/app/node_modules/av/src/sources/buffer.js:49:21)
at Immediate. (/usr/src/app/node_modules/av/src/sources/buffer.js:4:59)
at runCallback (timers.js:693:18)
at tryOnImmediate (timers.js:664:5)
at processImmediate (timers.js:646:5)
at process.topLevelDomainCallback (domain.js:121:23) [nodemon] app crashed - waiting for file changes before starting...

This looks like a mixed approach of Promise and async-await.
What if you tried a pure approach such as
const AudioContext = require('web-audio-api').AudioContext;
const context = new AudioContext();
const calcTempo = async (buffer) => {
let audioBuffer;
try {
audioBuffer = await context.decodeAudioData(buffer);
} catch (e) {
console.log(e)
}
}
as suggested here: https://developer.mozilla.org/en-US/docs/Web/API/BaseAudioContext/decodeAudioData

You are missing {} brackets for the callback function
try {
audioBuffer = await new Promise((resolve, reject) => {
context.decodeAudioData(buffer, resolve, reject)
});
}

Related

jest promise toThrow doesn't receive throw new Error

function getUserValue(){
return new Promise((resolve, reject) => {
readLine("enter the number : ", (enter) => {
if(enter.length > 3){
throw new Error("some error")
}
)};
}
async function play(){
try{
await getUserValue();
} catch(message){
console.log(message);
}
}
- jest -
test("exception test", expect(() => {
const app = new App();
app.play();
}).toThrow();
I want to receive the value through "getUserValue" using readLine of nodejs.
And I wanted to use async function to deal with errors. I tired to test this code using jest's toThrow. But it doesn't receive Error and doesn't work...
please help me.. What did I do wrong?
I really want to know how to handle error.

event stream node js large text file read doesn't wait for call back

function readFile()
{
return new Promise(function (resolve, reject) {
let totalLines = 0;
var s=fs.createReadStream("/var/www/uploads/"+filename);
s.pipe(es.split())
.pipe(
es.map(function (line, cb) {
cb(customFunction(line))
})
.on("error", function (err) {
reject(err);
})
.on("end", function () {
resolve("ok");
})
);
})
}
function customFuntion(line){
async()=>{
var res=await redisClient.get(line);
console.log(res)
}();
}
i am reading a large test file using createReadstream and event stream the issue i am facing is i want to check each number at line in redis but the read file get completed before my console.log in my custom function

Javascript Anti-Pattern - Returning a new Promise from async function

Is returning an unresolved manually created Promise from an async function considered an anti-pattern?
As async functions return promises by default, it is a little strange to build a new Promise and return it from the same async function.
I have two different methods, in the first one, I have doubts as to whether or not I am doing the new Promise constructor anti-pattern. In the other one, I am definitely sure that it is an anti-pattern.
First function:
export default async (uri) => {
const blob = await new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.onload = function () {
resolve(xhr.response);
};
xhr.onerror = function (e) {
reject(new TypeError("Network request failed"));
};
xhr.responseType = "blob";
xhr.open("GET", uri, true);
xhr.send(null);
});
return blob;
};
Second function:
export async function uploadImageToStorage(
imageUri,
storageFolder = "images",
stateObserver = undefined
) {
const blob = await uriToBlob(imageUri);
const imageId = blob._data.blobId;
const storageRef = storage.ref(storageFolder).child(imageId);
return new Promise((resolve, reject) => {
storageRef.put(blob).on(
"state_changed",
stateObserver,
function error(err) {
blob.close();
reject(err);
},
function complete() {
blob.close();
resolve(imageId);
}
);
});
}
Is it considered to be an anti-pattern the first method implementation?
In the second function, as storageRef.put(blob).on() doesn't return a Promise, my api is callback-based, I need to wrap it inside a Promise, resolving in a complete() callback. If I refactor it to:
export async function uploadImageToStorage(
imageUri,
storageFolder = "images",
stateObserver = undefined
) {
const blob = await uriToBlob(imageUri);
const imageId = blob._data.blobId;
const storageRef = storage.ref(storageFolder).child(imageId);
await new Promise((resolve, reject) => {
storageRef.put(blob).on(
"state_changed",
stateObserver,
function error(err) {
blob.close();
reject(err);
},
function complete() {
blob.close();
resolve(imageId);
}
);
});
return imageId;
}
The new implementation would not be considered as an anti-pattern right?
There is nothing wrong with this in either case. You have to return a Promise, but the API you are using is callback-based, so you have to wrap it in a manually created Promise at some point.
However, there's no point awaiting that Promise within your async function if all you're going to do is return the value that it resolved to. In that case you can just return the unresolved Promise directly.
After doing that, if you are no longer using await in the function, you could also remove the async keyword. But I would leave it in as a signal to the casual reader that the return value will be a Promise.

Cannot read property 'map' of undefined Node js

I am getting the Error, I am writing a function to monitor a path for. I am new to Node.js:
TypeError: Cannot read property 'map' of undefined
at C:\Users\a\Desktop\DL\file\filemonitor.js:15:14
at FSReqWrap.oncomplete (fs.js:149:20)
const Promise = require ('bluebird');
var fs = Promise.promisifyAll(require("fs"));
monitordir(monitorpath) {
var fileList = [];
return new Promise((resolve, reject) => {
fs.readdir(monitorpath,function(err, items) {
items.map((file) => {
fileList.push(file);
});
resolve(fileList);
});
})
}
Note: I don't see a package.json file either. Should I have a sucessful run to see it
When you run var fs = Promise.promisifyAll(require("fs")); it return a promise to you. So you can't execute a map of a promise.
I believe that you don't need a Promise to resolve fs module, my suggestion is you write something like that.
const Promise = require('bluebird');
const fs = require("fs");
const monitordir = path => {
return new Promise((resolve, reject) => {
fs.readdir(path, (error, items) => {
if (error) return reject(error)
return resolve(items);
})
})
}
Try following fix, see if it fits your needs:
monitordir(monitorpath)
{
var fileList = [];
return fs.readdir(monitorpath)
.then(function(err,items) {
items.map((file) => {
fileList.push(file); // fileList is ready here! do whatever you want before it resolves to caller
});
return fileList;
})
.catch(function(e) {
// something bad happened; throw error or handle it as per your needs
throw new Error(e);
});
}
For package.json you can run npm init command at your project directory it will create one for you.

how to throw and catch error if function runs longer than n seconds

I have a function of the form:
async someFunction () {
try {
someStuff()
} catch (err) {
doSomeCleanup()
}
}
Which gets called multiple times with workers from a queue. Now I have a new requirement that a worker should fail if it takes longer than 30 seconds to run this function with a given worker. My gut instinct was to whip up something like:
const timeoutCheck;
const time = new Date();
async someFunction () {
try {
timeoutCheck = setInterval(() => {
if (new Date() - time > 30000) throw new Error("timeout");
}, 2000);
someStuff()
} catch (err) {
doSomeCleanup()
} finally {
clearInterval(timeoutCheck);
}
}
But as I quickly learned the setInterval gets run outside the try/catch block so the error isn't caught inside the catch block but in the main app and the whole app crashes rather than just a worker failing. Is there a good way to contain this error in the try/catch block or another way to accomplish erroring into the try/catch block if the function runs more than 30 seconds?
You can use Promise.race()
let stop = () => new Promise((_, reject) =>
setTimeout(reject, 2999, "rejected"));
let fn = () => new Promise((resolve, _) =>
setTimeout(resolve, 3000, "resolved"));
let someStuff = data => console.log(data);
let doSomeCleanup = err => console.error(err);
Promise.race([fn(), stop()])
.then(doSomeStuff, doSomeCleanup);

Categories

Resources