Try and catch CATCH ERROR: ERROR STATUS: 403 (What the error is due to?) - node.js

I'm trying to deploy a smart contract, but before doing so I'm accessing${basePath}/build/ipfsMetasGeneric/_ipfsMetasResponse.json and picking up the metaData.metadata_uri to assign it to PREREVEAL_TOKEN_URI. It all works well until there (I can see on the terminal the console.log (PREREVEAL_TOKEN_URI)). But the app stop working right after as it catches an error and throws me the message CATCH ERROR: ERROR STATUS: 403.
I'm just quite puzzled since I don't understand why the try code runs all Ok but then throws me that error. I've hit a roadblock, would appreciate any help.
Thank you.
Code follows:
const path = require("path");
const basePath = process.cwd();
const fs = require("fs");
const yesno = require('yesno');
const {
fetchNoRetry,
} = require(`${basePath}/utils/functions/fetchWithRetry.js`);
let {
CHAIN,
GENERIC,
CONTRACT_NAME,
CONTRACT_SYMBOL,
METADATA_UPDATABLE,
ROYALTY_SHARE,
ROYALTY_ADDRESS,
MAX_SUPPLY,
MINT_PRICE,
TOKENS_PER_MINT,
OWNER_ADDRESS,
TREASURY_ADDRESS,
PUBLIC_MINT_START_DATE,
BASE_URI,
PREREVEAL_TOKEN_URI,
PRESALE_MINT_START_DATE,
PRESALE_WHITELISTED_ADDRESSES
} = require(`${basePath}/src/config.js`);
const deployContract = async () => {
const ok = await yesno({
question: `Is all REQUIRED contract information correct in config.js? (y/n):`,
default: null,
});
if(!ok) {
console.log("Exiting...");
process.exit(0);
}
if(GENERIC) {
try {
let jsonFile = fs.readFileSync(`${basePath}/build/ipfsMetasGeneric/_ipfsMetasResponse.json`);
let metaData = JSON.parse(jsonFile);
console.log (metaData);
if(metaData.response === "OK") {
if(!PREREVEAL_TOKEN_URI) {
PREREVEAL_TOKEN_URI = metaData.metadata_uri;
console.log (PREREVEAL_TOKEN_URI);
}
} else {
console.log('There is an issue with the metadata upload. Please check the /build/_ipfsMetasGeneric/_ipfsMetasResponse.json file for more information. Running "npm run upload_metadata" may fix this issue.');
}
} catch (err) {
console.log(`/build/_ipfsMetasGeneric/_ipfsMetasResponse.json file not found. Run "npm run upload_metadata" first.`);
console.log(`Catch: ${err}`);
process.exit(0);
}
} else {
try {
let jsonFile = fs.readFileSync(`${basePath}/build/ipfsMetas/_ipfsMetasResponse.json`);
let metaData = JSON.parse(jsonFile);
if(metaData.response === "OK") {
if(!BASE_URI) {
BASE_URI = metaData.metadata_directory_ipfs_uri;
}
} else {
console.log('There is an issue with the metadata upload. Please check the /build/_ipfsMetas/_ipfsMetasResponse.json file for more information. Running "npm run upload_metadata" may fix this issue.');
}
} catch (err) {
console.log(`/build/_ipfsMetasGeneric/_ipfsMetasResponse.json file not found. Run "npm run upload_metadata" first.`);
process.exit(0);
}
}
if (!fs.existsSync(path.join(`${basePath}/build`, "/contract"))) {
fs.mkdirSync(path.join(`${basePath}/build`, "contract"));
}
try {
const url = `https://api.nftport.xyz/v0/contracts/collections`;
const contract = {
chain: CHAIN.toLowerCase(),
name: CONTRACT_NAME,
symbol: CONTRACT_SYMBOL,
owner_address: OWNER_ADDRESS,
metadata_updatable: METADATA_UPDATABLE,
royalties_share: ROYALTY_SHARE,
royalties_address: ROYALTY_ADDRESS,
max_supply: MAX_SUPPLY,
mint_price: MINT_PRICE,
tokens_per_mint: TOKENS_PER_MINT,
treasury_address: TREASURY_ADDRESS,
public_mint_start_date: PUBLIC_MINT_START_DATE,
presale_mint_start_date: PRESALE_MINT_START_DATE,
base_uri: BASE_URI,
prereveal_token_uri: PREREVEAL_TOKEN_URI,
presale_whitelisted_addresses: PRESALE_WHITELISTED_ADDRESSES
};
const options = {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(contract),
};
const response = await fetchNoRetry(url, options);
fs.writeFileSync(`${basePath}/build/contract/_deployContractResponse.json`, JSON.stringify(response, null, 2));
if(response.response === "OK") {
console.log(`Contract deployment started.`);
} else {
console.log(`Contract deployment failed`);
}
console.log(`Check /build/contract/_deployContractResponse.json for more information. Run "npm run get_contract" to get the contract details.`);
} catch (error) {
console.log(`CATCH: Contract deployment failed`, `ERROR: ${error}`);
}
};
deployContract();

Related

Jasmine reporter publishing data to prometheus overwrites previous job & metrics

I am trying to write a reporter in jasmine that pushes data to prometheus. I am able to execute the tests and report them in one go but as soon as I re-execute these tests the existing job with the published metrics just gets overwritten with new data. What I want is to attach metrics to an existing job without removing the data that already exists.
This will allow me to run the specs in parallel as well, which can be done but the prometheus data just keeps being overwritten.
masterReporter.js
const PrometheusUtil = require("../utils/prometheusUtil");
class masterReporter {
async suiteDone(result) {
const prometheusUtil = new PrometheusUtil("http://localhost:9091", process.env.BASEURL);
await prometheusUtil.setTestExecutionMetrics(
{"region": prometheusUtil.region,
"spec_name": result.fullName, "tenant": process.env.BASEURL});
}
}
module.exports = masterReporter;
prometheusUtil.js
const client = require("prom-client");
class PrometheusUtil {
constructor(baseUrl, environment) {
this.environment = environment;
this.baseUrl = baseUrl;
this.name = environment.replace("https://", "").replace(".com", "")
.replaceAll(".", "_").replaceAll("-", "_").replaceAll("/", "");
this.testExecution = new client.Gauge({
name: this.name,
help: "Gauge for test execution results storing region info.",
labelNames: ["region", "tenant", "spec_name", "failure_classification_value"],
});
this.gateway = new client.Pushgateway(baseUrl);
this.setRegion(environment);
}
async setTestExecutionMetrics(value, number) {
try {
this.setRegion(this.environment);
this.testExecution.set(value, number);
this.gateway.pushAdd({jobName: this.name}, function(err, resp, body) {
if (err) {
console.log(err);
}
if (body) {
console.log(body);
}
});
} catch (error) {
console.log(error);
}
}
setRegion(baseUrl) {
if (baseUrl.includes(".us.")) {
this.region = "US";
}
else {
console.log(`Sorry, region could not be defined for ${baseUrl}.`);
}
return this.region;
}
}
module.exports = PrometheusUtil;

Why am I only getting Mailgun.js error in Cloud Run?

I'm trying to send an email using Mailgun's npm client - Mailgun.js.
When sending in development mode, everything works correctly. But when I upload the Node server to Cloud Run, something breaks.
Here is the code in the sendEmail helper file:
import formData from 'form-data';
import Mailgun from 'mailgun.js';
const sendEmail = async ({ to, subject, text, attachment, scheduledDate }) => {
const mailgun = new Mailgun(formData);
const mg = mailgun.client({
username: 'api',
key: process.env.MAILGUN_KEY,
url: 'https://api.eu.mailgun.net'
});
const data = {
from: `<myemail#mydomain.com>`,
to,
subject,
text
};
if (attachment) {
data.attachment = attachment;
}
if (scheduledDate) {
data['o:deliverytime'] = new Date(scheduledDate).toUTCString();
}
try {
const result = await mg.messages.create(process.env.MAILGUN_DOMAIN, data);
if (result.status && result.status !== 200) {
throw ({ code: result.status, message: result.message });
}
return true;
} catch(err) {
console.log(err);
return { error: err };
}
};
export default sendEmail;
And then in another file:
import { Router } from 'express';
import generateInvoicePDF from '../helpers/generateInvoicePDF.js';
import sendEmail from '../helpers/sendEmail.js';
const router = Router();
router.post('/email', async (req, res, next) => {
try {
const file = await generateInvoicePDF(invoice);
if (file?.error) {
throw ({ code: pdf.error.code, message: pdf.error.message });
}
const email = await sendEmail({
to: 'testemail#example.com',
subject: 'Invoice',
text: 'Test',
attachment: { filename: 'Invoice', data: file }
});
if (email?.error) {
throw ({ code: email.error.code, message: email.error.message });
}
res.status(200).json({ success: true });
} catch(err) {
next(err);
}
});
export default router;
The error I get when in production mode in Cloud Run's logs is:
TypeError: fetch failed
at Object.processResponse (node:internal/deps/undici/undici:5575:34)
at node:internal/deps/undici/undici:5901:42
at node:internal/process/task_queues:140:7
at AsyncResource.runInAsyncScope (node:async_hooks:202:9)
at AsyncResource.runMicrotask (node:internal/process/task_queues:137:8) {
cause: TypeError: object2 is not iterable
at action (node:internal/deps/undici/undici:1661:39)
at action.next (<anonymous>)
at Object.pull (node:internal/deps/undici/undici:1709:52)
at ensureIsPromise (node:internal/webstreams/util:172:19)
at readableStreamDefaultControllerCallPullIfNeeded (node:internal/webstreams/readablestream:1884:5)
at node:internal/webstreams/readablestream:1974:7
}
Why the hell does it work in development mode on my local machine, but not when uploaded to Cloud Run?
For anyone struggling with something similar - I eventually figured out the problem.
On my local machine, where everything was working as expected, I'm using Node v16.15.0, whereas in the Dockerfile, I had specified
FROM node:latest
and therefore Cloud Run was using a newer version, which led to the problems...
I've now deployed using version 16.15.0 and everything works fine

How to make kuzzle-device-manager plugin API actions works?

I successfully installed and loaded kuzzle-device-manager in the backend file:
import { Backend } from 'kuzzle';
import { DeviceManagerPlugin } from 'kuzzle-device-manager';
const app = new Backend('playground');
console.log(app.config);
const deviceManager = new DeviceManagerPlugin();
const mappings = {
updatedAt: { type: 'date' },
payloadUuid: { type: 'keyword' },
value: { type: 'float' }
}
deviceManager.devices.registerMeasure('humidity', mappings)
app.plugin.use(deviceManager)
app.start()
.then(async () => {
// Interact with Kuzzle API to create a new index if it does not already exist
console.log(' started!');
})
.catch(console.error);
But when i try to use controllers from that plugin for example device-manager/device with create action i get an error output.
Here is my "client" code in js:
const { Kuzzle, WebSocket } = require("kuzzle-sdk")
const kuzzle = new Kuzzle(
new WebSocket('KUZZLE_IP')
)
kuzzle.on('networkError', error => {
console.error('Network Error: ', error);
})
const run = async () => {
try {
// Connects to the Kuzzle server
await kuzzle.connect();
// Creates an index
const result = await kuzzle.query({
index: "nyc-open-data",
controller: "device-manager/device",
action: "create",
body: {
model: "model-1234",
reference: "reference-1234"
}
}, {
queuable: false
})
console.log(result)
} catch (error) {
console.error(error.message);
} finally {
kuzzle.disconnect();
}
};
run();
And the result log:
API action "device-manager/device":"create" not found
Note: The nyc-open-data index exists and is empty.
We apologize for this mistake in the documentation, the device-manager/device:create method is not available because the plugin is using auto-provisioning until the v2.
You should send a payload to your decoder, the plugin will automatically provision the device if it does not exists https://docs.kuzzle.io/official-plugins/device-manager/1/guides/decoders/#receive-payloads

Jest Test suite failed to run - AssertionError [ERR_ASSERTION]: opts.entryPoint required

We had a test running successfully for our code that uses the notifications-node-client to send emails, eg
import { NotifyClient } from 'notifications-node-client';
import notify from './notify';
import config from '../../../config';
jest.mock('fs');
jest.mock('notifications-node-client');
describe('notify', () => {
const EMAIL = 'user#test.com';
const REGION_GB = 'gb';
const REGION_NI = 'ni';
const feedbackOptions = {
personalisation: {
satisfactionLevel: 'satisfied',
improvements: 'improvements',
},
};
test('for original GB submission sendEmail should be called and true returned', async () => {
NotifyClient.prototype.sendEmail.mockReturnValue({
body: {
id: 1,
},
});
expect(await notify(EMAIL, 'submissionSuccess', REGION_GB)).toBeTruthy();
expect(NotifyClient.prototype.sendEmail).toHaveBeenCalledWith(
config.notify.templates.submissionSuccess.gb,
EMAIL,
undefined,
);
});
...
Having swapped out our Winston logging solution to use #dwp/node-logger, the 'notify' tests now do not run, failing with
● Test suite failed to run
AssertionError [ERR_ASSERTION]: opts.entryPoint required
at new Thrift (node_modules/thriftrw/thrift.js:64:5)
at Object.<anonymous> (node_modules/jaeger-client/src/thrift.js:21:20)
at Object.<anonymous> (node_modules/jaeger-client/src/reporters/remote_reporter.js:15:1)
All of the other test suites in the project still run successfully.
Could anyone point me in the right direction about what change to make?
The code that we're testing is
import { NotifyClient } from 'notifications-node-client';
import config from '../../../config/index';
import { RegionKeys } from '../../../config/types';
import logger from '../../../xxxx/lib/logger';
type TemplateId = 'submissionSuccess' | 'supportingEvidence' | 'feedbackTemplateId';
type FeedbackOptions = {
personalisation: {
satisfactionLevel: string,
improvements: string,
},
reference?: string,
}
const { apiKey, templates, proxy } = config.notify;
export default async function notify(
email: string,
templateId: TemplateId,
region: RegionKeys,
options?: FeedbackOptions,
): Promise<boolean> {
let notifyTemplate;
let notifyApiKey;
let notifyOptions;
try {
if (templateId === 'feedbackTemplateId' && !options) {
throw new Error(`Unable to send email - mismatch between template ID (${templateId}) and options supplied`);
} else if (options && templateId !== 'feedbackTemplateId') {
notifyOptions = {};
} else {
notifyOptions = options;
}
const notifyClient = new NotifyClient(apiKey[region]);
notifyClient.setProxy(proxy);
notifyTemplate = templateId === 'feedbackTemplateId' ? templates.feedbackTemplateId : templates[templateId][region];
logger.debug(`apiKey: ${notifyApiKey}`);
logger.debug(`notify template Id: ${notifyTemplate}`);
logger.debug(`proxy: ${JSON.stringify(proxy)}`);
const response = await notifyClient.sendEmail(notifyTemplate, email, notifyOptions);
if (response.body) {
logger.info(`confirmation email sent to ${email} and relates to message id ${response.body.id}`);
}
return true;
} catch (err: any) {
logger.error(`there was an error sending the message: ${err.message}`);
return false;
}
}

How can i get many details as possible about error using React Error boundry get error details?

Im tring to catch more details when error accuring.
when the error is accuring im using node api server to catch the error and save in log file.
i simulated a Network Error and tring to get many details as possible.
when i console.log the error in frontend im getting this:
withFormHandler.js:28 Uncaught Error: Error: Network Error
at Object.componentDidUpdate (withFormHandler.js:28)
...
but i cant send this information using my api.
all im getting in the server side is an empty object.
so how can i catch and send many details as possible about the error and write it to the log file?
this is my ErrorBoundry component:
class ErrorBoundary extends React.Component {
state = {
hasError: false,
error: { message: "", stack: "" },
info: { componentStack: "" },
};
static getDerivedStateFromError = (error) => {
return { hasError: true };
};
componentDidCatch = (error, info) => {
this.setState({ error, info });
axios
.get(`http://localhost:5001/api/logs/error`, {
params: {
error: error.message,
details: info,
// details:error ---> this is also not give me information i need
},
})
.catch(() => {});
};
render() {
const { hasError, error, info } = this.state;
const { children } = this.props;
return hasError ? <ErrorComponent message={error.message} /> : children;
}
}
this is the server side handle:
router.get("/error", (req, res) => {
const errorMessage = req.query.error;
const details = req.query.details; -----> return an empty object :(
const logFile = "./logs/debug.log";
if (errorMessage) {
let error = errorMessage + "\r\n" + details;
fs.appendFile(logFile, error, function (err) {
// callback or something
});
}
});

Resources