Where do I check the debugging results of adonis api query? - node.js

I read the docs from here : https://docs.adonisjs.com/guides/database/debugging#pretty-print-queries
And I try like this :
import { HttpContextContract } from '#ioc:Adonis/Core/HttpContext'
import Database from '#ioc:Adonis/Lucid/Database'
import Event from '#ioc:Adonis/Core/Event'
export default class UsersController {
public async index({ params, response }: HttpContextContract) {
const results = await Database
.query()
.select('*')
.from('users as a')
.innerJoin('posts as b', 'a.id', 'b.user_id')
.groupBy('a.id')
Event.on('db:query', Database.prettyPrint)
return response.status(200).json({ code: 200, status: 'success', data: results })
}
}
I try using the pretty print queries like that and I call the query. Then I check on the terminal and postman too. But I don't find the result
Where do I check the debugging results of adonis api query?
Please help. Thanks

Inside file .adonisrc.json add preloads events value
{
"preloads": [
"./start/routes",
"./start/kernel",
"./start/events", // here
],
}
and create a new file start/events.js add example code as documented
import Event from '#ioc:Adonis/Core/Event'
import Database from '#ioc:Adonis/Lucid/Database'
import Logger from '#ioc:Adonis/Core/Logger'
import Application from '#ioc:Adonis/Core/Application'
Event.on('db:query', (query) => {
if (Application.inProduction) {
Logger.debug(query)
} else {
Database.prettyPrint(query)
}
})

Related

Console.log Refuses to Print Statements in Mutation File

I am using a PostgreSQL database, with a GraphQL / NodeJS server. One of the mutations is giving me extensive problems, due to its intrinsically complex nature. I am trying to use console.log statements throughout so I can track the data, but not a SINGLE statement prints. Now, before you all jump on me and say that the mutation probably isn't getting hit, that's not the case. I'm getting return values, the mutation is occurring (I checked the Network section of the Browser to confirm. I also have error handlers that do not get triggered) but nothing gets printed.
The code for one of the two mutations called simultaneously is as follows...
import db from "../../../../utils/generatePrisma.js";
import checkOwnerAuth from "../../../../utils/checkAuthorization/check-owner-auth.js";
import checkManagerAuth from "../../../../utils/checkAuthorization/check-manager-auth.js";
export default {
Mutation: {
scorecardToolCreateWeeklyReports: async (_, {
token,
dspId,
role,
transporterId,
date,
feedbackStatus,
feedbackMessage,
feedbackMessageSent,
rank,
tier,
delivered,
keyFocusArea,
fico,
seatbeltOffRate,
speedingEventRate,
distractionsRate,
followingDistanceRate,
signalViolationsRate,
deliveryCompletionRate,
deliveredAndRecieved,
photoOnDelivery,
attendedDeliveryAccuracy,
dnr,
podOpps,
ccOpps
}, context) => {
let owner;
let manager;
if (role === 'OWNER') {
owner = await checkOwnerAuth(token)
}
if (role === 'MANAGER') {
manager = await checkManagerAuth(token)
}
const foundDriver = await db.driver.findFirst({
where: {
transporterId: transporterId,
dspId: dspId
}
})
if (!foundDriver) {
throw new Error('Driver does not exist')
}
console.log("\n-----------------------\n Found Driver in scoreCardToolCreateWeeklyReport")
console.log(foundDriver)
try {
return await db.weeklyReport.create({
data: {
driver: {
connect: {
id: foundDriver.id
}
},
date: date,
feedbackStatus: feedbackStatus,
feedbackMessage: feedbackMessage,
feedbackMessageSent: feedbackMessageSent,
rank: rank,
tier: tier,
delivered: delivered,
keyFocusArea: keyFocusArea,
fico: fico,
seatbeltOffRate: seatbeltOffRate,
speedingEventRate: speedingEventRate,
distractionsRate: distractionsRate,
followingDistanceRate: followingDistanceRate,
signalViolationsRate: signalViolationsRate,
deliveryCompletionRate: deliveryCompletionRate,
deliveredAndRecieved: deliveredAndRecieved,
photoOnDelivery: photoOnDelivery,
attendedDeliveryAccuracy: attendedDeliveryAccuracy,
dnr: dnr,
podOpps: podOpps,
ccOpps: ccOpps
}
}).then( (resolved) => {
console.log(resolved)
})
} catch (error) {
console.log("\n---------------\n Error in WeeklyReportCreation")
console.log(error)
throw new Error(error)
}
}
}
}
Interestingly enough, the return I recieve is exactly what I would want and would expect, however, it does not persist, and on any refresh, rerender, or movement between pages and there's no model, its like the mutation just never even happened. When the mutation is called from the Frontend, it runs somewhat as expected. Upon hitting inspect on the browser and looking at the response section in the Network tab, I get the following...
{"data":
{"scorecardToolCreateWeeklyReports":
{"id":"91c7dd10-0af8-4fc7-9906-20643700c97f",
"createdAt":"2022-04-12T18:09:09.787Z",
"date":"11-24-22",
"hadAccident":false,
"feedbackMessage":"null",
"feedbackMessageSent":false,
"feedbackStatus":"Fantastic",
"acknowledged":false,
"acknowledgedAt":null,
"rank":1,
"tier":"Fantastic",
"delivered":116,
"keyFocusArea":"null",
"fico":"850",
"seatbeltOffRate":"Coming Soon",
"speedingEventRate":"Coming Soon",
"distractionsRate":"Coming Soon",
"followingDistanceRate":"Coming Soon",
"signalViolationsRate":"Coming Soon",
"deliveryCompletionRate":"100",
"deliveredAndRecieved":"100",
"photoOnDelivery":"100",
"attendedDeliveryAccuracy":0,
"dnr":0,
"podOpps":54,
"ccOpps":0,
"__typename":"WeeklyReport"}}}
The mutation shown before is then placed into a minor resolver...
import GraphQLJSON from "graphql-type-json";
import scorecardToolCreateDriverAccounts from "./mutations/scorecardToolCreateDriverAccounts.js";
import scorecardToolCreateWeeklyReports from "./mutations/scorecardToolCreateWeeklyReports.js";
export default {
Query: {
},
Mutation: {
...scorecardToolCreateDriverAccounts.Mutation,
...scorecardToolCreateWeeklyReports.Mutation
},
JSON: GraphQLJSON
}
And then this minor resolver is then imported into the main resolver
import GraphQLJSON from 'graphql-type-json';
// NEW RESOLVERS
import ownerReslovers from './owner/ownerResolvers.js';
import managerResolvers from './manager/managerResolvers.js';
import driverResolvers from './driver/driverResolvers.js';
import dspResolvers from './dsp/dspResolvers.js';
import weeklyReportResolvers from './weeklyReport/weeklyReportResolvers.js';
import scorecardResolvers from './scorecardTool/scorecardResolvers.js';
import chatroomResolvers from './chatrooms/chatroomResolvers.js';
import shiftPlannerResolvers from './shiftPlanner/shiftPlannerResolvers.js';
import messagesResolvers from './messages/messagesResolvers.js';
import accidentResolvers from './accidents/accidentResolvers.js';
import shiftPlannerDatesResolvers from './shiftPlannerDates/shiftPlannerDatesResolvers.js';
import shiftResolvers from './shift/shiftReolvers.js';
// ADDITIONAL RESOLVERS
import additionalResolvers from './additional/additionalResolvers.js';
export default {
Query: {
...ownerReslovers.Query,
...managerResolvers.Query,
...driverResolvers.Query,
...dspResolvers.Query,
...weeklyReportResolvers.Query,
...shiftPlannerResolvers.Query,
...chatroomResolvers.Query,
...messagesResolvers.Query,
...accidentResolvers.Query,
...shiftPlannerDatesResolvers.Query,
...shiftResolvers.Query,
...scorecardResolvers.Query,
...additionalResolvers.Query
},
Mutation: {
...ownerReslovers.Mutation,
...managerResolvers.Mutation,
...driverResolvers.Mutation,
...dspResolvers.Mutation,
...weeklyReportResolvers.Mutation,
...shiftPlannerResolvers.Mutation,
...chatroomResolvers.Mutation,
...messagesResolvers.Mutation,
...accidentResolvers.Mutation,
...shiftPlannerDatesResolvers.Mutation,
...shiftResolvers.Mutation,
...scorecardResolvers.Mutation,
...additionalResolvers.Mutation
},
JSON: GraphQLJSON,
}
It turns out my final thought was correct. The mutation is 100% being run, and the log statements are being hit.
The issue is due to AWS EC2 CodePipeline deployment. The backend server is perpetually being run on AWS's end, so the console where the logs occur is no longer my VSC terminal, but the instance's AWS console.
This is also the same with the front end, where if I run the code locally, none of the new logs get hit. I can only see ALL of the frontend logs if I am on the IP adress in the browser, not the localhost.
This all being said, I currently have no idea how to view the console in AWS and if anyone was privy to that information and cared to share that would be greatly appreciated

Can I execute a function in response to a failed assert in TestCafe?

We are using Testcafe for our regression tests and I would like to enhance the test logging of failed asserts by adding any messages from the browser console to the output. According to the Testcafe documentation, this code will print "The test has failed" in case the given element is not visible on the page:
await t.expect(Selector('#elementId').visible).ok("The test has failed");
According to the doco, the browser console messages can be read using the the t.getBrowserConsoleMessages method, but I have not been able to combine them into one statement like e.g.
await t.expect(Selector('#elementId').visible).ok(console.log(await t.getBrowserConsoleMessages()));
as this always processes the getBrowserConsoleMessages method and outputs the console messages, regardless of whether the assert is successful or not.
Is there a way to make this work only if the assert fails?
I seems you just need to call getBrowserConsoleMessages conditionally.
To get the expected behavior, you can use the following code:
import { Selector } from 'testcafe';
fixture`A set of examples that illustrate how to use TestCafe API`
.page`http://devexpress.github.io/testcafe/example/`;
test('Test1', async t => {
const isVisible = await Selector('#developer-name').visible;
if (!isVisible)
console.log(await t.getBrowserConsoleMessages())
await t.expect(isVisible).ok();
});
test('Test2', async t => {
const isVisible = await Selector('#developer-name2').visible;
if (!isVisible)
console.log(await t.getBrowserConsoleMessages())
await t.expect(isVisible).ok();
});
Here is how I got this working myself:
import { Selector } from 'testcafe';
async function objToString (obj) {
return Object.entries(obj).reduce((str, [p, val]) => {
return `${str}${p}::${val}\n`;
}, '');
}
fixture('My test')
.page('https://myurl.com')
test('Test1', async t => {
....
await t.expect(Selector('#elementId').visible).ok(await objToString(await browser.getBrowserConsoleMessages()));
....
});

AWS Lambda with typescript getting Cannot read property of undefined inside async handler

Typescript newbie here. I am working on an AWS Lambda function by using typescript with classes. I am exporting an async handler at the end. When I invoke my function from AWS SAM CLI then I am getting error of;
{"errorType":"TypeError","errorMessage":"Cannot read property 'test' of undefined","stack":["TypeError: Cannot read property 'test' of undefined"," at Runtime.handler (/var/task/src/lambda/create-cost-lambda.js:12:56)"," at Runtime.handleOnce (/var/runtime/Runtime.js:66:25)"]}
create-cost-lambda.ts
class CreateCostLambda {
private readonly foobarRepository: FoobarRepository;
constructor() {
this.foobarRepository = new FoobarRepository();
}
async handler(event: APIGatewayProxyEventV2) : Promise<APIGatewayProxyResultV2> {
const result = await this.foobarRepository.test();
console.log(result);
return {
body: JSON.stringify(result),
statusCode: 200,
};
}
}
export const { handler } = new CreateCostLambda();
Here is a very basic class represents a repository.
foobar-repository.ts
export class FoobarRepository {
private readonly awesomeValue: string;
constructor() {
this.awesomeValue = 'John Doe';
}
async test(): Promise<string> {
return this.awesomeValue;
}
}
I am almost sure it is because of the way I am exporting the handler and how aws-sam internally runs the handler. But I might be wrong and it can be typescript thing that I am missing. Please let me know if you need more information and thanks a lot for the help!
The short version is if you pass a function from an class, it loses it's reference to this.
I would solve this as follows:
const createCostLambda = new CreateCostLambda();
export const handler = createCostLambda.handler.bind(createCostLambda);
You can also ask yourself, does this need to be a class? The answer is: probably not. There's nothing gained from this in your sample.
const foobarRepository = new FoobarRepository();
export async function handler(event: APIGatewayProxyEventV2) : Promise<APIGatewayProxyResultV2> {
const result = await foobarRepository.test();
console.log(result);
return {
body: JSON.stringify(result),
statusCode: 200,
};
}
Fewer lines, no unneeded state. Javascript is not Java =)

Trouble with Async/Await on APIs response

Hey guys that's my first app using Node.js and I'm having trouble working with async/ await.
On my index.js I have three methods that depends on each-other, but can't figure out how to do it.
Can someone lend me a hand and teach me in in the work?
async function Millennium_SendSMS() {
// search for orders on Millennium's API
let orders = await new listOrders().listOrders();
// filter orders
let filteredOrders = new filterOrders().filterOrders(orders);
// send sms to the filtered orders
filteredOrders.map(order => {
new sendSmsRequest(order).sendSmsRequest();
})
}
When I try to run the code above, I get an error message from the filterOrders method saying that that the var orders is undefined.
Update:
listOrders class
class listOrders {
listOrders() {
axios.get('http://mill.com/api/millenium_eco/pedido_venda/listapedidos')
.then(listOrders => {
return listOrders;
})
}
}
You haven't returned the promise from listOrders function within your class so there is nothing to resolve for the await function
Add a return statement to listOrders function like below and it would work
class listOrders {
listOrders() {
return axios.get('http://mill.com/api/millenium_eco/pedido_venda/listapedidos')
.then(listOrders => {
return listOrders;
})
}
}

How to instantiate Dynamoose Model from DynamoDB's AttributeValue format?

I am using Dynamodb streams to do some work on records as they are added or modified to my table. I am also using Dynamoose models in my application.
The Dynamodb stream event passes an event object to my node.js lambda handler that includes the objects record.dynamoDb.NewImage and record.dynamoDb.OldImage. However, these objects are in DynamoDB's AttributeValue format including all of the data types ('S' for string), rather than a normal javascript object. So record.id becomes record.id.S.
Dynamoose models allow you to instantiate a model from an object, like so: new Model(object). However, it expects that argument to be a normal object.
I know that Dynamoose has a dynamodb parser, I think its Schema.prototype.dynamodbparse(). However, that doesn't work as expected.
import { DYNAMODB_EVENT } from '../../constant';
import _get from 'lodash/get';
import { Entry } from '../../model/entry';
import { applyEntry } from './applyEntry';
async function entryStream(event) {
await Promise.all(
event.Records.map(async record => {
// If this record is being deleted, do nothing
if (DYNAMODB_EVENT.Remove === record.eventName) {
return;
}
// What I've tried:
let entry = new Entry(record.dynamodb.NewImage);
// What I wish I could do
entry = new Entry(Entry.schema.dynamodbparse(record.dynamodb.newImage));
await applyEntry(entry);
})
);
}
export const handler = entryStream;
So is there a way to instantiate a Dynamoose model from DynamoDB's AttributeValue format? Has anyone else done this?
The alternative, is that I simply extract the key from the record, and then make a trip to the database using Model.get({ id: idFromEvent }); But I think that would be inefficient, since the record was just handed to me from the stream.
I solved it by using AWS.DynamoDB.Converter.unmarshall to parse the object before passing to Dynamoose.
import { DYNAMODB_EVENT } from '../../constant';
import _get from 'lodash/get';
import { Entry } from '../../model/entry';
import { applyEntry } from './applyEntry';
// https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/DynamoDB/Converter.html#unmarshall-property
var AWS = require('aws-sdk');
var parseDynamo = AWS.DynamoDB.Converter.unmarshall;
async function entryStream(event) {
await Promise.all(
event.Records.map(async record => {
// If this record is being deleted, do nothing
if (DYNAMODB_EVENT.Remove === record.eventName) {
return;
}
entry = new Entry(parseDynamo(record.dynamodb.newImage));
await applyEntry(entry);
})
);
}
export const handler = entryStream;

Resources