heroku node js create folder issue - node.js

I have express app which works fine on localhost, but when I deploy it to heroku it doesn't create any folders, although all other functionality works fine
in order to specify the path to the file i use nodejs path and save it to mongoDB
How it looks on Localhost:5000 after uploading file inside project:
MongoDB file path field:
C:\Users\inbec\OneDrive\New folder\Documents\Code\servers\CooperateFront-back\files/60f063de9e95e729f05dfcfb/60f0642b9e95e729f05dfd02/60f064369e95e729f05dfd07/Screenshot_3.png
How it looks with Heroku:
Heroku CLI: heroku run bash -a cooperatefront-back
~/files $ cd 60f063de9e95e729f05dfcfb
bash: cd: 60f063de9e95e729f05dfcfb: No such file or directory
In Browser:
Cannot GET
/app/files/60f063de9e95e729f05dfcfb/60f05fe09d17a600223700d7/60f05fe59d17a600223700db/Screenshot_1.png
MongoDB file path field: /app/files/60f063de9e95e729f05dfcfb/60f05fe09d17a600223700d7/60f05fe59d17a600223700db/Screenshot_1.png
index.js
app.use(filePathMiddleWare(path.resolve(__dirname, "files")))
app.use(fileUpload({}))
app.use("/files",express.static("files"))
filepath-middleware:
function filePath(path) {
return function (req, res, next) {
req.filePath = path
next()
}
}
module.exports = filePath
FileService:
class FileService {
createDor(req,file) {
console.log(req.filePath, "filePath")
const filePath = `${req.filePath}\\${file.user}\\${file.path}`
return new Promise(((resolve, reject) => {
try {
if (!fs.existsSync(file)) {
fs.mkdirSync(filePath)
return resolve({message: "File was created"})
} else {
return reject({message: "File already exists"})
}
} catch (e) {
console.log(e)
return reject({message: "File error"})
}
}))
}
}

Found ussue:
no need to specify the /app folder to get file
{myHerokuSite}/files/60f06d3f41e750002225c04a/60f06d4641e750002225c051/60f06d4c41e750002225c055/photo_2021-02-22_09-33-17.jpg
and just in case changed \\ to /
const filePath = ${req.filePath}\\${file.user}\\${file.path} =>
${req.filePath}/${file.user}/${file.path}

I know you have already answerd your own question here but just be aware that Heroku is essentially a CASS service (container as a service)
This means ephemeral storage is not persistent. Each time you restart, redeploy all items will be lost.
A better approach would be do use an object store like S3. This will allow you to store the images on a persistent volume that will allow your application to keep working even with restarts as the code runs on the container and dynamic / user create assets will be stored in the object store and shared across all running instances.

Related

Slash command registers command from wrong folder discord.js14

I'm tired of trying to solve this. First off, here is my deployment code
const { REST, Routes } = require('discord.js');
const fs = require('node:fs');
const { client_id } = require('./config.json')
const commands = [];
// Grab all the command files from the commands directory you created earlier
const commandFiles = fs.readdirSync('./slashCommands').filter(file => file.endsWith('.js'));
// Grab the SlashCommandBuilder#toJSON() output of each command's data for deployment
for (const file of commandFiles) {
const command = require(`./slashCommands/${file}`);
commands.push(command.data.toJSON());
}
// Construct and prepare an instance of the REST module
const rest = new REST({ version: '10' }).setToken(process.env.TOKEN);
// and deploy your commands!
(async () => {
try {
console.log(`Started refreshing ${commands.length} application (/) commands.`);
// The put method is used to fully refresh all commands in the guild with the current set
const data = await rest.put(
Routes.applicationCommands(client_id),
{ body: commands },
);
console.log(`Successfully reloaded ${data.length} application (/) commands.`);
} catch (error) {
// And of course, make sure you catch and log any errors!
console.error(error);
}
})();
It is supposed to get the command from the "slashCommand" folder. So I run 'node deploy-commands.js' and it works.
The problem is when I do the slash command '/ping', I get this error:
/home/runner/Nocinel/commands/ping.js:8
message.reply('🏓 **Ball is going over the net...**').then(m => { m.edit(`**🏓 Pong!\n:stopwatch: Uptime: ${Math.round(message.client.uptime / 60000)} minutes\n:sparkling_heart: Websocket Heartbeat: ${message.client.ws.ping}ms\n:round_pushpin: Rountrip Latency: ${m.createdTimestamp - message.createdTimestamp}ms**`) });
^
TypeError: m.edit is not a function
at /home/runner/Nocinel/commands/ping.js:8:73
repl process died unexpectedly: exit status 1
Now this error indicates that I am running a command from my "command" folder rather than my "slashCommand" folder. Which doesnt make sense because I explicitly coded it to only get commands from the "slash command folder"
I have restarted, deleted, waited for an hour, and tested it multiple times, it always gives the same disappointing result. I see absolutely nothing wrong with my code.
There is no problem with registring comannd (deploy-comannds.js is only registring comannds not using making them work). Problem have to be in your index.js you have to handle interaction comannds to your folder slashComannds. Registring comannds was sucessfull.
Documentation:
https://discordjs.guide/creating-your-bot/command-handling.html#loading-command-files

How to delete repo.lock from IPFS in Next.js (or how to get rid of the error)

I am trying to build a Next.js web application in which the browser is an IPFS node. When I am to make the IPFS node, I get this error:
This is the code where I make the IPFS instance:
import * as IPFSCORE from 'ipfs-core';
const IPFS = (() => {
let IPFSInstance = undefined;
const createInstance = async () => {
return await IPFSCORE.create();
}
return {
getInstance: async () => {
if (!IPFSInstance) IPFSInstance = await createInstance();
return IPFSInstance;
}
}
})();
export default IPFS;
Here is a little more background: I experimented with IPFS on Node.js first. There I got this repo.lock error when I saved my app and then it refreshed (with nodemon). So I thought that making a singleton kind of code in order to create the IPFS instance only once will do the job, and it did. But at the same time, when working locally with Node.js, the repo.lock file was saved on my machine, and when I got the error (prior to making the singleton), I just deleted the file. When I switched to Next.js, I can't find the repo.lock file, like it's not on my machine. Where is the file? Or how can I get rid of this error? Or should I take another approach in order to create the IPFS instance only once?

Is there a way to control the nuxt cache when deploying?

When using Nuxt, I ask questions.
When I distributed the site I built, the cache problem caused it to malfunction.
There are two cases below. Is there any way to solve them?
If built, the file names of js and css will be renamed to hash values, but it was not reflected by viewing old cache in browser.
Create applications using vue-native webview The webview in the application looked up the old cache. To apply the changed js, css, how do I remove the cache from the past?
https://github.com/nuxt/nuxt.js/issues/4764#issuecomment-713469389
Implementation of this one:
Add a plugin filename route.client.js
Include in nuxt.config.json
function getClientAppVersion() {
return localStorage.getItem('APP_VERSION') ?? 0
}
function setClientAppVersion(version) {
return localStorage.setItem('APP_VERSION', version)
}
export default ({ app }) => {
app.router.afterEach((to, from) => {
fetch("/version.json").then((serverPromise) =>
serverPromise.json().then((response) => {
const latestVersion = response.version
const clientStoredVersion = getClientAppVersion()
if (clientStoredVersion != latestVersion) {
window.location.reload(true)
setClientAppVersion(latestVersion)
}
else return
}))
})}
Add version.jon file
{
"version": "9.1"
}

reading a packaged file in aws lambda package

I have a very simple node lambda function which reads the contents of packaged file in it. I upload the code as zip file. The directory structure is as follows.
index.js
readme.txt
Then have in my index.js file:
fs.readFile('/var/task/readme.txt', function (err, data) {
if (err) throw err;
});
I keep getting the following error NOENT: no such file or directory, open '/var/task/readme.txt'.
I tried ./readme.txt also.
What am I missing ?
Try this, it works for me:
'use strict'
let fs = require("fs");
let path = require("path");
exports.handler = (event, context, callback) => {
// To debug your problem
console.log(path.resolve("./readme.txt"));
// Solution is to use absolute path using `__dirname`
fs.readFile(__dirname +'/readme.txt', function (err, data) {
if (err) throw err;
});
};
to debug why your code is not working, add below link in your handler
console.log(path.resolve("./readme.txt"));
On AWS Lambda node process might be running from some other folder and it looks for readme.txt file from that folder as you have provided relative path, solution is to use absolute path.
What worked for me was the comment by Vadorrequest to use process.env.LAMBDA_TASK_ROOT. I wrote a function to get a template file in a /templates directory when I'm running it locally on my machine with __dirname or with the process.env.LAMBDA_TASK_ROOT variable when running on Lambda:
function loadTemplateFile(templateName) {
const fileName = `./templates/${templateName}`
let resolved
if (process.env.LAMBDA_TASK_ROOT) {
resolved = path.resolve(process.env.LAMBDA_TASK_ROOT, fileName)
} else {
resolved = path.resolve(__dirname, fileName)
}
console.log(`Loading template at: ${resolved}`)
try {
const data = fs.readFileSync(resolved, 'utf8')
return data
} catch (error) {
const message = `Could not load template at: ${resolved}, error: ${JSON.stringify(error, null, 2)}`
console.error(message)
throw new Error(message)
}
}
This is an oldish question but comes up first when attempting to sort out whats going on with file paths on Lambda.
Additional Steps for Serverless Framework
For anyone using Serverless framework to deploy (which probably uses webpack to build) you will also need to add the following to your webpack config file (just after target: node):
// assume target: 'node', is here
node: {
__dirname: false,
},
Without this piece using __dirname with Serverless will STILL not get you the desired absolute directory path.
I went through this using serverless framework and it really was the file that was not sent in the compression. Just add the following line in serverless.yml:
package:
individually: false
include:
- src/**
const filepath = path.resolve('../../filename.text');
const fileData2 = fs.readFileSync(process.env.LAMBDA_TASK_ROOT + filepath, 'utf-8');
I was using fs.promises.readFile(). Couldn't get it to error out at out. The file was there, and LAMBDA_TASK_ROOT seemed right to me as well. After I changed to fs.readFileSync(), it worked.
I hade the same problem and I tried applying all these wonderful solutions above - which didn't work.
The problem was that I setup one of the folder name with one letter in upper case which was really lowercase.
So when I tried to fetch the content of /src/SOmething/some_file.txt
While the folder was really /src/Something/ - I got this error...
Windows (local environment) is case insensitive while AWS is not!!!....

Understanding ExpressJS application start-up

I am struggling with how application start-up works in Express. I am going to explain my use-case:
I have a configuration-Manager module which is used by all other application modules to load required configuration. I am setting configuration in app.listen:
app.listen(9000, function () {
try
{
config_manager.setSiteConfig();
console.log('settings..!!!')
}
catch(err)
{
console.log(err.stack);
}
});
In another module of the same application I call the Configuration-Manager function to load config, but it returns empty. Code is something like this:
var config_manager = require('configuration-manager');
console.log(config_manager.loadConfig()); // returns empty object {}
I am running the application using node app.js. The empty object gets printed first then ('settings..!!!'). Does Express compile the script before calling app.listen()? How do I make sure that my configuration is set before compilation/loading other files?
Express indeed first processes all statements in a file, basically anything that isn't in a function on startup.
In your case var config_manager = require('configuration-manager');
console.log(config_manager.loadConfig()); // returns empty object {} is executed before your app.listen because you are requering the config before the app.listen.
You're best off processing your configuration right after the first time it is required (if app.js is your main file, this means the first time it comes across a require statement pointing to configuration-manager in any file).
This should make your code work:
var config_manager = require('configuration-manager');
try {
config_manager.setSiteConfig();
} catch(err) {
console.log(err.stack);
}
console.log(config_manager.loadConfig()); // returns empty object {}
and then
app.listen(9000, function () {
console.log('settings..!!!', config_manager.loadConfig()) // Should correctly print your config
});
If this doesn't work the problem does not lay in the order of execution.

Resources