Receiving error message when trying to connect to GraphQL api over websocket using k6 - websocket

I'm going to perform a subscription test using k6 for the graphql api that uses Hasura. Here's what I've tried:
import ws from "k6/ws";
import { check } from "k6";
export const myFunc = (url, access_token, id, query) => {
const headers = {
Authorization: access_token,
};
const res = ws.connect(url, { headers }, function (socket) {
socket.on("open", function open() {
console.log(`VU ${__VU}: connected`);
socket.send(
JSON.stringify({
type: "connection_init",
payload: headers,
})
);
console.log("sending query");
socket.send(
JSON.stringify({
type: "start",
payload: {
query: query,
variables: {
id,
}
},
})
);
});
...
socket.on("message", function (msg) {
console.log(`VU ${__VU}: received message: ${msg}`);
const message = JSON.parse(msg);
if (message.type == "connection_ack")
console.log("Connection Established with WebSocket");
if (message.type == "data") console.log(`Message Received: ${message}`);
});
...
};
And the logs with error:
INFO[0001] VU 1: connected source=console
INFO[0001] sending query source=console
INFO[0001] VU 1: received message: {"type":"ka"} source=console
INFO[0001] VU 1: received message: {"type":"connection_ack"} source=console
INFO[0001] Connection Established with WebSocket source=console
INFO[0001] VU 1: received message: {"type":"ka"} source=console
INFO[0001] VU 1: received message: {"type":"connection_error","payload":"parsing ClientMessage failed: Error in $: When parsing the record StartMsg of type Hasura.GraphQL.Transport.WebSocket.Protocol.StartMsg the key id was not present."} source=console
Why am I receiving the key id not present error? I have no idea what that means and couldn't find anything when I searched for it.

When you send a message over established websocket connection, the protocol dictates that you need to send id too. See this link.
Example payload:
{
"id": "1",
"type":"start",
"payload": {
"variables":{},
"query":"query MyQuery {\n test {\n id\n }\n}\n"
}
}
id can be any string decided by the client. When server send the response back, it will contain the same id. With parsing ClientMessage failed error message, Hasura is complaining that it cannot find the id.

Related

SQS send message error using #aws-sdk node js at AWS lambda

I am trying to send message from my AWS Lambda to AWS SQS but it isn't quiet working and throwing me the error.
2022-12-26T14:58:31.651Z 282ada00-ea4a-45b6-afe4-e3a7f16e8c5a INFO MissingParameter: The request must contain the parameter Label.
at throwDefaultError (/var/task/node_modules/#aws-sdk/smithy-client/dist-cjs/default-error-handler.js:8:22)
at deserializeAws_queryAddPermissionCommandError (/var/task/node_modules/#aws-sdk/client-sqs/dist-cjs/protocols/Aws_query.js:292:51)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async /var/task/node_modules/#aws-sdk/middleware-serde/dist-cjs/deserializerMiddleware.js:7:24
at async /var/task/node_modules/#aws-sdk/middleware-signing/dist-cjs/middleware.js:14:20
at async /var/task/node_modules/#aws-sdk/middleware-retry/dist-cjs/retryMiddleware.js:27:46
at async /var/task/node_modules/#aws-sdk/middleware-logger/dist-cjs/loggerMiddleware.js:5:22
at async sendToSQS (/var/task/sendToSqs.js:28:20)
at async exports.handler (/var/task/index.js:19:22) {
'$fault': 'client',
'$metadata': {
httpStatusCode: 400,
requestId: 'bf137e9a-24bc-52bd-9416-22b99c6b82f5',
extendedRequestId: undefined,
cfId: undefined,
attempts: 1,
totalRetryDelay: 0
},
Type: 'Sender',
Code: 'MissingParameter',
Detail: ''
}
I am not sure what parameters and in which way I need to include to make it work.
This is my code for sending message, where from my main module I send a simple data value as part of my message to be sent to SQS.
const { SQSClient, AddPermissionCommand } = require("#aws-sdk/client-sqs");
const sendToSQS=async(data)=>{
const client = new SQSClient({ region: "eu-west-1" });
var params = {
DelaySeconds: 0,
MessageAttributes: {
"Author": {
DataType: "String",
StringValue: "event params"
},
},
MessageGroupId:`${data}`,
MessageBody:JSON.stringify(data),
QueueUrl:"https://sqs.eu-west-1.amazonaws.com/000011110000/Salesforce-cqd-orders-delayer-retry"
};
try{
const command = new AddPermissionCommand(params);
let queueRes = await client.send(command);
console.info("[LAMBDA/#sqs] retry mechanism has succeeded. Data sent to SQS successfully")
console.log(queueRes)
const response = {
statusCode: 200,
body: "Data sent from lambda to sqs successfully.",
};
return response
}catch(error){
console.error("[LAMBDA/#s] retry mechanism has failed. Data wasn't sent to SQS")
console.log(error)
const response = {
statusCode: 200,
body: "Lambda to SQS error",
};
return response;
}
}
module.exports={sendToSQS}
Your message has delaySeconds which is not required and MessageGroupId which is only required for FIFO queue.
You can check sendMessage code reference from here AWS Wiki
Also, check this API reference for Send Message

"[Network] undefined" when trying to use subscriber - URQL

I am trying to set up a subscriber to log some output on the creation of a new Message.
Currently using Urql, with ApolloServerExpress on the backend.
I am receiving an error from the useSubscription method which I am logging to the console :
message: "[Network] undefined"
name: "CombinedError"
I know for sure my backend is working as I can subscribe using the Graphiql playground just fine.
As far as front end goes, I have followed almost exactly as the example in the Urql docs.
WS Client:
const wsClient = createWSClient({
url: "ws://localhost:4000/graphql",
});
Subscriber Exchange:
subscriptionExchange({
forwardSubscription(operation) {
return {
subscribe: (sink) => {
const dispose = wsClient.subscribe(operation, sink);
return {
unsubscribe: dispose,
};
},
};
},
}),
MessageList Component:
const newMessages = `
subscription Messages {
newMessage {
content
status
sender {
id
email
}
recipient {
id
email
}
}
}
`;
...
const handleSub = (messages: any, newMessage: any) => {
console.log("Messages: ", messages);
console.log("newMessages: ", newMessage);
};
const [res] = useSubscription({ query: newMessages }, handleSub);
console.log("Res: ", res);
I was getting the same error when using subscriptions with urql. In my case, I was able to do console.log(error.networkError); which gave a much more helpful error message than [Network] undefined.
You can read more about errors in urql here.
The error I got from error.networkError was:
Event {
"code": 4400,
"isTrusted": false,
"reason": "{\"server_error_msg\":\"4400: Connection initialization failed: Missing 'Authorization' or 'Cookie' header in JWT authenticati",
}
I was able to fix it by adding authentication to my subscription exchange setup. Here's the code I'm using now:
const wsClient = createWSClient({
url: "wss://your-api-url/graphql",
connectionParams: async () => {
// Change this line to however you get your auth token
const token = await getTokenFromStorage();
return {
headers: {
Authorization: `Bearer ${token}`,
},
};
},
});
Ended up chalking graphql-ws and switched over to subscriptions-transport-ws.
Fixed my issues.

Proactive Message, Received error 401 "Authorization has been denied for this request"

I'm trying to send a proactive message using botframework in Nodejs (Teams channel), but a received 401 error.
I make some searches and I found that the error can be possible with the trust service URL, but I have already done that part.
My adpter config
const {
BotFrameworkAdapter,
} = require('botbuilder');
const { MicrosoftAppCredentials } = require('botframework-connector');
const adapter = new BotFrameworkAdapter({
appId: process.env.MICROSOFT_APP_ID,
appPassword: process.env.MICROSOFT_APP_PASSWORD
})
Send proactive message code
adapter.continueConversation(address, async (t) => {
MicrosoftAppCredentials.trustServiceUrl(process.env.MICROSOFT_BOT_SERVICE_URL);
await t.sendActivity(model.render());
}).then((r) => {
console.log("continue")
console.log(r)
res.status(200).send({
status: "OK"
})
}).catch((e) => {
console.log(e);
res.send("ERRO " + e)
});
Request and response, with my AppId and conversation ID.
statusCode: 401,
> request: WebResource {
> streamResponseBody: false,
> url: 'https://smba.trafficmanager.net/amer/v3/conversations/a%3A1MUpsVB7CH-6BTiSUHxOkMhv05saxu9O7qe0zRNPR04PCvXp-6QzsoYKpT-oykqyJpu8SgbawTkbUDauiBGF9bIeG9qg56Ts6lpEGgY6SSrMMj5YL_K-yxOJ5jjoqIrJQ/activities',
> method: 'POST',
> headers: HttpHeaders { _headersMap: [Object] },
> body: '{"type":"message","serviceUrl":"https://smba.trafficmanager.net/amer/","channelId":"msteams","from":{"id":"c96afa27-addb-4bc8-80fb-c0317380bf1a","name":"Luna"},"conversation":{"id":"a:1MUpsVB7CH-6BTiSUHxOkMhv05saxu9O7qe0zRNPR04PCvXp-6QzsoYKpT-oykqyJpu8SgbawTkbUDauiBGF9bIeG9qg56Ts6lpEGgY6SSrMMj5YL_K-yxOJ5jjoqIrJQ"},"text":"Achei aqui! A OV de número 0001302956","inputHint":"acceptingInput"}',
> query: undefined,
> formData: undefined,
> withCredentials: false,
> abortSignal: undefined,
> timeout: 0,
> onUploadProgress: undefined,
> onDownloadProgress: undefined,
> operationSpec: {
> httpMethod: 'POST',
> path: 'v3/conversations/{conversationId}/activities',
> urlParameters: [Array],
> requestBody: [Object],
> responses: [Object],
> serializer: [Serializer]
> }
> },
> response: {
> body: '{"message":"Authorization has been denied for this request."}',
> headers: HttpHeaders { _headersMap: [Object] },
> status: 401
> },
> body: { message: 'Authorization has been denied for this request.' }
> }
configs
send proactive message
Request and response
I just saw this was a duplicate of your GitHub issue. I'll post my answer here for others:
The issue is that in sendMessage.f.js, you're instantiating a new BotFrameworkAdapter, which differs from the one instantiated in gateway.f.js, which you use to create the conversationReference.
They look the same because you're passing in the same appId/password, but their BotIdentityKey differs because the key is generated using Symbol(), which as you may know, guarantees a unique key gets generated every time it's called, even with the same input. This BotIdentityKey is used in some auth chaching, deep in the code.
If you want to keep them in separate files, I'd recommend exporting your adapter in gateway.f.js and importing it in sendMessage.f.js.
Note: I confirmed this was the issue by running Sample 57, verifying it worked, then instantiating a new adapter in the proactive message section. I, too, got the 401 error.

Coinbase-pro for Node.js - Websocket connection breaking with error: read ECONNRESET

I'm currently stuck with an issue I'm getting with the coinbase-pro-node npm package (https://github.com/coinbase/coinbase-pro-node). I'm connecting to the matches channel and listening for messages there but the connection with the Websocket breaks after a few hours without telling me much. I can't trace back the problem and it doesn't happen on the same intervals. Sometimes it breaks just minutes after I run the script. Thanks for the help.
The code:
const CoinbasePro = require('coinbase-pro');
var coinbaseWs = '';
function connect() {
coinbaseWs = new CoinbasePro.WebsocketClient(
['BTC-USD'],
'wss://ws-feed.pro.coinbase.com',
{
key: 'xxxx',
secret: 'xxxx',
passphrase: 'xxxx',
},
{ channels: ['matches'] }
);
coinbaseWs.on('message', async data => {
console.log(data)
});
coinbaseWs.on('error', err => {
console.error("Connection with Coinbase websocket failed with error: " + err);
console.log("Error stack trace: " + err.stack);
});
coinbaseWs.on('close', () => {
console.error("Connection with Coinbase websocket closed!");
});
}
connect();
Error stack:
Error: read ECONNRESET
File "internal/stream_base_commons.js", line 167, in TLSWrap.onStreamRead
it does break from time to time for no apparent reason. All you can do is listen for the heartbeat messages and use those to decide whether to re-initiate a new websocket feed. I raised a similar query directly with the coinbase pro/gdax customer support.

Where do I handle feathersjs/socketio-client connection error

I'm using feathers with socketio in backend. The client is listening and everything works well.
I want to handle the 'server not responding' error and I don't find where can I do that?
The error thrown by the server:
"Unhandled promise rejection
Object { type: "FeathersError", name: "Timeout", message: "Timeout of 5000ms exceeded calling find on newsfeed", code: 408, className: "timeout", data: {…}, errors: {}, stack: "FeathersError#webpack-internal:///./node_modules/#feathersjs/errors/lib/index.js:58:19\nTimeout#webpack-internal:///./node_modules/#feathersjs/errors/lib/index.js:135:3\nsend/</timeoutId<#webpack-internal:///./node_modules/#feathersjs/transport-commons/lib/client.js:66:9\n" }"
It is correct, the 'promise' is not handled! Where do I handle?
I tried adding catch on each line just to see what works but without success:
import feathers from '#feathersjs/feathers'
import socketio from '#feathersjs/socketio-client'
import io from 'socket.io-client'
const socket = io('http://localhost:3030/', {transports: ['websocket']});
socket.on("connect_failed", er=>console.error('Error connecting to server: ', er));
const restApi = feathers()
.configure(socketio(socket));
try {
restApi.service('/newsfeed');
restApi.on("connect_failed", er=>console.error('Error connecting to server: ', er));
}
catch (er) {
console.error('Error connecting to server: ', er)
}
export default restApi
The timeout error is coming from a particular request so you have to handle it wherever you are making the request.
restApi.service('/newsfeed').find()
If you're using async/await, you can wrap your service call in a try/catch or my personal favorite is just putting a catch on the call;
// try/catch
try {
const response= await restApi.service('/newsfeed').find();
catch(e) {
// handle e
}
//just use catch
const response= await restApi.service('/newsfeed').find().catch(e => {
// handle e
});
If you're using promises, just use a catch:
restApi.service('/newsfeed').find().then(response => {
// handle response
}).catch(e => {
// handle e
});

Resources