Sails app crash when not calling skipper upload - sails.js

If I call req.file('files') and not calling updload (for example because I throw validation error) the app crashes.
const files = req.file('files')
if (!files || files.length === 0) {
throw "MISSING_ARGUMENTS"; // intentally fails here
}
file.upload() // not reaching here
error :
events.js:173
throw er; // Unhandled 'error' event
^
Error: EMAXBUFFER: An Upstream (`NOOP_files`) timed out before it was plugged into a receiver. It was still unused after waiting 4500ms. You can configure this timeout by changing the `maxTimeToBuffer` option.
at Timeout.<anonymous> (../node_modules/sails/node_modules/skipper/standalone/Upstream/Upstream.js:86:15)
at listOnTimeout (timers.js:327:15)
at processTimers (timers.js:271:5)
Emitted 'error' event at:
at Upstream.fatalIncomingError (../node_modules/sails/node_modules/skipper/standalone/Upstream/prototype.fatalIncomingError.js:95:8)
at Timeout.<anonymous> (../node_modules/sails/node_modules/skipper/standalone/Upstream/Upstream.js:93:12)
at listOnTimeout (timers.js:327:15)
at processTimers (timers.js:271:5)
Waiting for the debugger to disconnect...
Error: EMAXBUFFER: An Upstream (`NOOP_files`) timed out before it was plugged into a receiver. It was still unused after waiting 4500ms. You can configure this timeout by changing the `maxTimeToBuffer` option.
at Timeout.<anonymous> (../node_modules/sails/node_modules/skipper/standalone/Upstream/Upstream.js:86:15)
at listOnTimeout (timers.js:327:15)
at processTimers (timers.js:271:5)
Emitted 'error' event at:
at Upstream.fatalIncomingError (../node_modules/sails/node_modules/skipper/standalone/Upstream/prototype.fatalIncomingError.js:95:8)
at Timeout.<anonymous> (../node_modules/sails/node_modules/skipper/standalone/Upstream/Upstream.js:93:12)
at listOnTimeout (timers.js:327:15)
at processTimers (timers.js:271:5)

I was also facing the same issue, in my case, I checked with allParams() that will prevent app from crashing.
const fileDetials = !('image' in req.allParams()) ? req.file('fieldName') : '';

Related

How to catch/Capture "javax.net.ssl.SSLHandshakeException: Failed to create SSL connection" while sending message over java vert.x Eventbus

I am trying to use SSL over eventbus. To test the failure case I tried sending message to the eventbus from another verticle in same cluster by passing some different keystore.
I am getting below exception on console but it is not failing the replyHandler hence my code is not able to detect the SSL exception.
my code:
eb.request("ping-address", "ping!", new DeliveryOptions(), reply -> {
try {
if (reply.succeeded()) {
System.out.println("Received reply " + reply.result().body());
} else {
System.out.println("An exception " + reply.cause().getMessage());
}
} catch (Exception e) {
System.out.println("An error occured" + e.getCause());
}
});
Exception on console:
**javax.net.ssl.SSLHandshakeException: Failed to create SSL connection**
at io.vertx.core.net.impl.ChannelProvider$1.userEventTriggered(ChannelProvider.java:109)
at io.netty.channel.AbstractChannelHandlerContext.invokeUserEventTriggered(AbstractChannelHandlerContext.java:341)
at io.netty.channel.AbstractChannelHandlerContext.invokeUserEventTriggered(AbstractChannelHandlerContext.java:327)
at io.netty.channel.AbstractChannelHandlerContext.fireUserEventTriggered(AbstractChannelHandlerContext.java:319)
at io.netty.handler.ssl.SslHandler.handleUnwrapThrowable(SslHandler.java:1249)
at io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1230)
at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1271)
at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:505)
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:444)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:283)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:374)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:360)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:352)
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1422)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:374)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:360)
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:931)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:700)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:635)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:552)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:514)
at io.netty.util.concurrent.SingleThreadEventExecutor$6.run(SingleThreadEventExecutor.java:1044)
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.lang.Thread.run(Thread.java:813)
Caused by: javax.net.ssl.SSLException: Received fatal alert: bad_certificate
at sun.security.ssl.Alerts.getSSLException(Alerts.java:208)
at sun.security.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1647)
at sun.security.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1615)
at sun.security.ssl.SSLEngineImpl.recvAlert(SSLEngineImpl.java:1781)
at sun.security.ssl.SSLEngineImpl.readRecord(SSLEngineImpl.java:1070)
at sun.security.ssl.SSLEngineImpl.readNetRecord(SSLEngineImpl.java:896)
at sun.security.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:766)
at javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:624)
at io.netty.handler.ssl.SslHandler$SslEngineType$3.unwrap(SslHandler.java:282)
at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1329)
at io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1224)
... 20 more
But handler is failing for timeout after 30 sec.
Timed out after waiting 30000(ms) for a reply. address: __vertx.reply.8419a431-d633-4ba8-a12e-c41fd5a4f37a, repliedAddress: ping-address
I want to capture the SSL exception immediately and handle it. Please guide me how can I Capture/catch this exception.
I tried with below code. Below one is able to handle the exception and I am not getting reply result from called event-bus. Reply result is always null. (value is always null)
MessageProducer<Object> ms = eb.sender("ping-address");
ms.write("ping!", reply -> {
if (reply.succeeded()) {
reply.map(value -> {
System.out.println("Received reply " + value);
return reply;
});
} else {
System.out.println("No reply");
System.out.println("An exception : " + reply.cause().getMessage());
}
});
You can't catch this exception because the Vert.x clustered EventBus implementation buffers messages when the nodes are not connected together. The message could be sent later if the problem is only temporary.
If you want to be notified earlier, you could set a lower timeout in DeliveryOptions.

How to handle idle_in_transaction_session_timeout?

When we set idle_in_transaction_session_timeout, the database will terminate connections that are idle for some time.
This works as expected, but I wonder how we should deal with this situation in the aplication code.
We are using pg-promise 10.3.1.
Details of the test:
we set the connection pool size to 1, so that we only have a single session
we set the for the idle-transaction-session-timeout to 2.5 sec:
SET idle_in_transaction_session_timeout TO 2500
now the active transaction will be in state idle in transaction:
see What can cause “idle in transaction” for “BEGIN” statements
now we start a transaction and sleep for 5 seconds
after 2.5sec the database will terminate the session and send an error to the client:
pgp-error error: terminating connection due to idle-in-transaction timeout
after another 2.5sec the transactional code tries to send a query (via the already terminated session), and this fails as expected:
dbIdle failed Error: Client has encountered a connection error and is not queryable
then pg-promise will try to rollback the transaction which will also fail (also expected, I guess)
But now we start a new query and also this query fails with
dbCall failed Client has encountered a connection error and is not queryable
is this expected? I was hoping that pg-promise can somehow remove the "broken" connection from the pool and that we could get a new one
obvously this is not the case, so how should we deal with this situation: i.e. how to recover, so that we can send new queries to the database?
Code example:
import pgPromise, { IMain } from "pg-promise";
import * as dbConfig from "./db-config.json";
import { IConnectionParameters } from "pg-promise/typescript/pg-subset";
const cll = "pg";
console.time(cll);
const pgp: IMain = pgPromise({
query(e) {
console.timeLog(cll,`> ${e.query}`);
},
error(e, ctx) {
console.timeLog(cll,"pgp-error", e);
}
});
const connectParams: IConnectionParameters = {
...dbConfig,
application_name: "pg-test",
max: 1
};
const db = pgp(connectParams);
/**
* #param timeoutMs 0 is no timeout
*/
async function setDbIdleInTxTimeout(timeoutMs: number = 0) {
await db.any("SET idle_in_transaction_session_timeout TO $1;", timeoutMs);
}
async function dbIdle(sleepTimeSec: number) {
console.timeLog(cll, `starting db idle ${sleepTimeSec}`);
const result = await db.tx(async t => {
await new Promise(resolve => setTimeout(resolve, sleepTimeSec * 1000));
return t.one("Select $1 as sleep_sec", sleepTimeSec);
});
console.timeLog(cll, result);
}
async function main() {
await setDbIdleInTxTimeout(2500);
try {
await dbIdle(5);
} catch (e) {
console.timeLog(cll, "dbIdle failed", e);
}
try {
await db.one("Select 1+1 as res");
} catch (e) {
console.timeLog(cll, "dbCall failed", e);
}
}
main().finally(() => {
pgp.end();
});
Console output (removed some useless lines):
"C:\Program Files\nodejs\node.exe" D:\dev_no_backup\pg-promise-tx\dist\index.js
pg: 23.959ms > SET idle_in_transaction_session_timeout TO 2500;
pg: 28.696ms starting db idle 5
pg: 29.705ms > begin
pg: 2531.247ms pgp-error error: terminating connection due to idle-in-transaction timeout
at TCP.onStreamRead (internal/stream_base_commons.js:182:23) {
name: 'error',
severity: 'FATAL',
code: '25P03',
}
pg: 2533.569ms pgp-error Error: Connection terminated unexpectedly
pg: 5031.091ms > Select 5 as sleep_sec
pg: 5031.323ms pgp-error Error: Client has encountered a connection error and is not queryable
pg: 5031.489ms > rollback
pg: 5031.570ms pgp-error Error: Client has encountered a connection error and is not queryable
pg: 5031.953ms dbIdle failed Error: Client has encountered a connection error and is not queryable
pg: 5032.094ms > Select 1+1 as res
pg: 5032.164ms pgp-error Error: Client has encountered a connection error and is not queryable
pg: 5032.303ms dbCall failed Error: Client has encountered a connection error and is not queryable
Process finished with exit code 0
This issue #680 has been fixed in pg-promise 10.3.5

[Frisby]Can't report correctly if test is fail

I wrote RestAPI TEST with frisby.js.
If Test result is True, There is no probrem.
But If Test result is False, Frisby doesn't report correctly on Linux.(report correctly on windows)
following are sample codes:
const frisby = require('frisby');
const Joi = frisby.Joi;
describe('TEST', () => {
it ('should return a status of 200', (done) =>{
frisby
.get('https://jsonfeed.org/feed.json')
.expect('status', 400) //deliberately error
.done(done);
});
});
If this spec.js run on Windows, result is below
> jasmine-node .
F
Failures:
1) TEST should return a status of 200
Message:
Expected 'AssertionError: HTTP status 400 !== 200
at FrisbySpec.status ([mydirpath]\expects.js:25:12)
(snip)
But, If spec.js run on Linux(Ubuntu), result is below
(node:28704) UnhandledPromiseRejectionWarning: AssertionError [ERR_ASSERTION]: HTTP status 400 !== 200
at FrisbySpec.status (/home/nsco/jen_work/frisby/node_modules/frisby/src/frisby/expects.js:25:12)
at FrisbySpec._addExpect.response (/home/nsco/jen_work/frisby/node_modules/frisby/src/frisby/spec.js:368:23)
at FrisbySpec._runExpects (/home/nsco/jen_work/frisby/node_modules/frisby/src/frisby/spec.js:260:24)
at _fetch.fetch.then.then.responseBody (/home/nsco/jen_work/frisby/node_modules/frisby/src/frisby/spec.js:139:14)
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:160:7)
(node:28704) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:28704) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
F
Failures:
1) TEST should return a status of 200
Message:
timeout: timed out after 5000 msec waiting for spec to complete
Stacktrace:
undefined
"Failures:" section is displayed as "Timeout".
(On windows, displayed as "Expected 'AssertionError: HTTP status 400 !== 200".It is correct.)
Environments:
frisby#2.0.11
jasmine-node#1.14.5
node/9.4.0
Ubuntu16.04

Stop query if there Is an error (Parse.com)

At the moment the app it crashing if there is no internet connection when running the query. How do I tell the query to stop if there is an error and prevent this?
Thanks
Error Below:
Error: Error Domain=NSURLErrorDomain Code=-1009 "The Internet connection appears to be offline." UserInfo=0x1702e0d80 {NSUnderlyingError=0x1742569e0 "The Internet connection appears to be offline.", NSErrorFailingURLStringKey=https://api.parse.com/2/find, NSErrorFailingURLKey=https://api.parse.com/2/find, _kCFStreamErrorDomainKey=12, _kCFStreamErrorCodeKey=8, NSLocalizedDescription=The Internet connection appears to be offline.} (Code: 100, Version: 1.2.21)
2014-12-01 20:36:39.257 AppName[5903:999805] Network connection failed. Making attempt 2 after sleeping for 1.546502 seconds.
In parse there you can handle errors for many things.
I think to stop a query if there is not internet connection you can use kPFErrorConnectionFailed
Ex.
var query = PFQuery()
query.findObjectsInBackgroundWithBlock{
(success:Bool!, error:NSError!)-> Void in
if (error == nil) {
//continue query
}
else{
if(error.code == kPFErrorConnectionFailed) {
//handle error
}
}
}

Handling Http errors in coffeescript

I am trying to handle a http request in coffeescript, but in case the server is down the app just dies with error below, and I can't find the right solution.
Code:
http.get "http://localhost:8080/health", (res) ->
status = res.statusCode
value = if status == 200 then 1 else 0
console.log value
server.push_metric metricPrefix , value
res.on 'error', () ->
colsone.log "Tomcat Disconected"
error:
events.js:71
throw arguments[1]; // Unhandled 'error' event
^
Error: connect ECONNREFUSED
at errnoException (net.js:770:11)
at Object.afterConnect [as oncomplete] (net.js:761:19)
I think you have to actively listen for the error in a separate event handler. Right now, you're attaching an event handler to the response (res), but it needs to be attached to the request object itself. See the docs.
req = http.get "http://localhost:8080/health", (res) ->
status = res.statusCode
value = if status == 200 then 1 else 0
console.log value
server.push_metric metricPrefix , value
req.on 'error', ->
console.log "Tomcat Disconected"
Also, you have a typo in your current error handler: colsone.log