How to set custom error in strong-error-handler when debug mode is false - error-handling

I'm using Loopback v3.x, and strong-error-handler for handling my project errors. The error response was fine in the development mode but when in production mode, it throws a different error back to the client.
I realised that it was the "debug": false" that makes it throw an { error: { statusCode: 500, message: 'Internal Server Error' } } (based from the Loopback documentation about strong-error-handler)
But I wanted to show my error in the production when I throw new Error('Error Messages') with "debug": false (to keep the sensitive data such as file paths, URLs, and stack traces out from exposure)
Below are my config files:
config.json
{
...
"remoting": {
"rest": {
"normalizeHttpPath": false,
"xml": false,
"handleErrors": false
}
}
}
middleware.development.json
{
"final:after": {
"strong-error-handler": {
"params": {
"debug": true,
"log": true,
"safeFields": [
"code"
]
}
}
}
}
middleware.json
{
"final:after": {
"strong-error-handler": {
"params": {
"debug": false,
"log": true,
"safeFields": [
"code"
]
}
}
}
}
I wanted the response to show the Error that I have thrown, like below:
Instead, now it receives:
I have went to strongloop-error-handler GitHub library but couldn't find any documentation about throwing the original error. Is it possible to do so?

So I went digging around the strong-error-handler library and found out that it is technically possible to do so if we set a statusCode into the error manually, and has to be within 400 - 499.
in buildResponseData() function:
if (data.statusCode >= 400 && data.statusCode <= 499) {
fillBadRequestError(data, err);
} else {
fillInternalError(data, err);
}
https://github.com/strongloop/strong-error-handler/blob/master/lib/data-builder.js#L37
and the fillBadRequestError() will return the original error
function fillBadRequestError(data, err) {
data.name = err.name;
data.message = err.message;
data.code = err.code;
data.details = err.details;
}
https://github.com/strongloop/strong-error-handler/blob/master/lib/data-builder.js#L69
So, before throwing the error, we can set:
const error = new Error();
error.name = 'Custom Error';
error.message = 'Error Message';
error.statusCode = 404;
throw error;
Then it will return the error even with "debug": false mode

Related

How to call function on XMLHttpRequest status = true in Vue 2? I get "this.xxxx not a function" error

I have the following code, which works fine except for the "makeToast" function that I'm trying to call when status response is true. I get a "this.makeToast is not a function" error on the console.
This function is working fine if I call it after the XMLHttpRequest code. The data is also not being assigned to the msgForm property. I could not figure out why. The "alert(..." message work fine.
<script>
import ToastMixins from '/src/mixins/ToastMixins'
let config = {
headers: {
}
}
export default {
name: 'ModalDestaque',
mixins: [
ToastMixins
],
methods: {
myFunction() {
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
console.log('onreadystatechange');
console.log('responseText 1', xhr.responseText);
this.loading = false;
if (xhr.status == 200) {
console.log('responseText 2', xhr.responseText);
let responseObj = JSON.parse(xhr.responseText);
console.log('responseObj', responseObj);
if (responseObj.status == true) {
//alert('Ok');
// this is not working:
this.msgForm = "Message success!";
this.makeToast('b-toaster-bottom-right', true, 'success');
} else {
alert('Not ok...');
}
}
}
};
}
}
}
What am I doing wrong?
I've found the solution while reading the docs at W3 Schools.
W3 Schools AJAX XMLHttp - Multiple Callback Functions
Although, I haven't found a working example anywhere.
In my code, at the button click event that triggers the XMLHttpRequest, I've added the function name "callToast" as a variable, so:
#click="onClickSubmit(myValue, myId, myTitle, callToast)"
Then in the script:
<script>
onClickSubmit(amount, id, title, cFunction) {
// stuff
if (xhr.status == 200) {
let responseObj = JSON.parse(xhr.responseText);
if (responseObj.status == true) {
// here I call the callToast function:
cFunction(this);
alert('Ok');
} else {
alert('Not ok...');
}
}
},
callToast() {
this.msgForm = "Message success!";
this.makeToast('b-toaster-bottom-right', true, 'success');
}
</script>

How to recover a error message from oData response [SAPUI5]

I had this issue and i searched a lot how to fix it, but i can't find any solution at the moment...
well, the issue is the next error message, i can write the error but i need a specific entry of this batch.
the code showed on the message box:
{
"message": "HTTP request failed",
"headers": {
"Content-Type": "application/xml;charset=utf-8",
"Content-Length": "1333",
"DataServiceVersion": "1.0"
},
"statusCode": "400",
"statusText": "Bad Request",
"responseText": "<?xml version=\"1.0\" encoding=\"utf-8\"?><error xmlns=\"http://schemas .microsoft.com/ado/2007/08/dataservices/metadata\"><code>SY/530</code><message xml:lang=\"es\">No posee permisos para el Centro seleccionado</message><innererror><application><component_id/><service_namespace>/SAP/</service_namespace><service_id>ZQMGW_LECTURATANQUE_SRV</service_id><service_version>0001</service_version></application><transactionid>9488BBDEFA9E11E685950000705EE2FB</transactionid><timestamp>20170224144147.5230000</timestamp><Error_Resolution><SAP_Transaction>Run transaction /IWFND/ERROR_LOG on SAP Gateway hub system and search for entries with the timestamp above for more details</SAP_Transaction><SAP_Note>See SAP Note 1797736 for error analysis (https: //service. sap .com/sap/support/notes/1797736)</SAP_Note><Batch_SAP_Note>See SAP Note 1869434 for details about working with $batch (https: //service. sap. com/sap/support/notes/1869434)</Batch_SAP_Note></Error_Resolution><errordetails><errordetail><code/><message>No posee permisos para el Centro seleccionado</message><propertyref/><severity>error</severity><target/></errordetail><errordetail><code>/IWBEP/CX_SD_GEN_DPC_BUSINS</code><message>No posee permisos para el Centro seleccionado</message><propertyref/><severity>error</severity><target/></errordetail></errordetails></innererror></error>"
}
i need to recover the message tag only, but i don't know how....
the code what i'm using is the native error handling for Sapui5 Fiori Apps:
constructor: function(oComponent) {
this._oResourceBundle = oComponent.getModel("i18n").getResourceBundle();
this._oComponent = oComponent;
this._oModel = oComponent.getModel();
this._bMessageOpen = false;
this._sErrorText = this._oResourceBundle.getText("errorText");
this._oModel.attachMetadataFailed(function(oEvent) {
var oParams = oEvent.getParameters();
this._showServiceError(oParams.response);
}, this);
this._oModel.attachRequestFailed(function(oEvent) {
var oParams = oEvent.getParameters("message");
// An entity that was not found in the service is also throwing a 404 error in oData.
// We already cover this case with a notFound target so we skip it here.
// A request that cannot be sent to the server is a technical error that we have to handle though
if (oParams.response.statusCode !== "404" || (oParams.response.statusCode === 404 && oParams.response.responseText.indexOf(
"Cannot POST") === 0)) {
this._showServiceError(oParams.response);
}
}, this);
},
/**
* Shows a {#link sap.m.MessageBox} when a service call has failed.
* Only the first error message will be display.
* #param {string} sDetails a technical error to be displayed on request
* #private
*/
_showServiceError: function(sDetails) {
if (this._bMessageOpen) {
return;
}
this._bMessageOpen = true;
MessageBox.error(
this._sErrorText, {
id: "serviceErrorMessageBox",
details: sDetails,
styleClass: this._oComponent.getContentDensityClass(),
actions: [MessageBox.Action.CLOSE],
onClose: function() {
this._bMessageOpen = false;
}.bind(this)
}
);
}
if someone knows how to recover that value, I'll be very greatful.
Greetings.
i fixed this issue, changing this part of the code
if (oParams.response.statusCode !== "404" || (oParams.response.statusCode === 404 && oParams.response.responseText.indexOf(
"Cannot POST") === 0)) {
this._showServiceError(oParams.response);
}
}, this);
to
if (oParams.response.statusCode !== "404" || (oParams.response.statusCode === 404 && oParams.response.responseText.indexOf(
"Cannot POST") === 0)) {
this._showServiceError($(oParams.response.responseText).find("message").first().text());
}
}, this);
Check if you have HCM_LRQ_CRE BSP application in your SAP ABAP Repository, actually it is an HCM Leave Request Fiori app. You can find there DataManager-dbg.js file. Look into parseErrorMessages method, it parses SAP messages nicely. Probably you can use it as a starting point.

CasperJS: exit not working

Trying to open random pages through casperJS start method but some pages are loading properly and some of them are not, so in this scenario it is not exiting from casperjs.
It is getting stuck in console then need to manually exit from console using CTR+C.
casper.start("some url", function() {
if(this.status().currentHTTPStatus == 200) {
casper.echo("page is loading");
} else {
casper.echo("page is in error ");
this.exit();
}
});
Wrap it by a then step with a global stepTimeout option.
Sample code:
var casper = require('casper').create({
stepTimeout: 10000 //10s
})
casper.start()
casper.then(funtion(){
casper.open(url)
})
casper.run()
Try bypass() to ignore the next thens.
casper.start("some url", function() {
if(this.status().currentHTTPStatus == 200) {
casper.echo("page is loading");
} else {
casper.echo("page is in error ");
this.bypass(2); // Will not execute the then functions.
}
}).then(function() {
// The 1st then function.
}).then(function() {
// The 2nd then function.
})
casper.run(function() {
this.echo('Something');
this.exit(); // <--- Here.
});

Ti.Media.showCamera not showing even if camera permissions are granted Android 6.0 Titanium

My development environment is mac osx, appcelerator sdk 5.3.0 and testing on google nexus Android 6.0. Ti.Media.showCamera not opening camera even if permissions are granted. Here is my code
function openCamera(parms) {
if (Ti.Media.hasCameraPermissions) {
Ti.API.error("Yes has camera permission");
Ti.Media.showCamera({
success : function(event) {
parms.source.image = newBlob;
},
cancel : function() {
Ti.API.error("User cancelled pictur selection");
},
error : function(error) {
var a = Ti.UI.createAlertDialog({
title : 'Camera Error'
});
if (error.code == Ti.Media.NO_CAMERA) {
a.setMessage("No Camera Found!");
} else {
a.setMessage('Unexpected Error: ' + error.code);
}
a.show();
},
mediaTypes : [Ti.Media.MEDIA_TYPE_PHOTO],
animated : true,
autoHide : true,
allowEditing : true,
saveToPhotoGallery : false,
showControls : true
});
} else {
Ti.API.error("No camera permission. Asking for Permission");
Ti.Media.requestCameraPermissions(function(e) {
Ti.API.error(JSON.stringify(e));
if (e.success === true) {
openCamera(parms);
} else {
alert("Access denied, error: " + e.error);
}
});
}
};
In console log this displayed
Yes has camera permission
[WARN] : InputEventReceiver: Attempted to finish an input event but
the input event receiver has already been disposed.
Would someone point me out what is wrong here.
Hiii I think you are missing brackets after hasCameraPermissions. hasCameraPermissions() is a method defined inside Ti.Media.
Use it like this:
if(hasCameraPermissions()){
//Do you code.....
}

Aborted upload causes Sails js/Skipper to crash

Ref: https://github.com/balderdashy/skipper/issues/49
Adapter: skipper-gridfs
Basic controller code:
req.file('fileTest')
.upload({
// You can apply a file upload limit (in bytes)
maxBytes: maxUpload,
adapter: require('skipper-gridfs'),
uri: bucketConnect,
saveAs : function (__newFileStream,cb) {
cb(null, __newFileStream.filename);
}
}, function whenDone(err, uploadedFiles) {
if (err) {
var error = { "status": 500, "error" : err };
return res.serverError(error);
}else {
I have a jQuery-File-Upload client ( https://blueimp.github.io/jQuery-File-Upload/ ) impementing the "cancel" procedure by using jqXHR abort described here (https://github.com/blueimp/jQuery-File-Upload/wiki/API ):
$('button.cancel').click(function (e) {
jqXHR.abort();
});
After the client aborts, the server crashes with the following message:
events.js:72
throw er; // Unhandled 'error' event
^
Error: Request aborted
at IncomingMessage.onReqAborted (.../node_modules/sails/node_modules/skipper/node_modules/multiparty/index.js:175:17)
at IncomingMessage.EventEmitter.emit (events.js:92:17)
at abortIncoming (http.js:1911:11)
at Socket.serverSocketCloseListener (http.js:1923:5)
at Socket.EventEmitter.emit (events.js:117:20)
at TCP.close (net.js:466:12)
I've used try/catch but it didn't work, the server crashes anyway.
I am not sure if this is a Skipper issue or a Multiparty issue -- my knowledge stops here ( https://github.com/andrewrk/node-multiparty/blob/master/index.js ):
function onReqAborted() {
waitend = false;
self.emit('aborted');
handleError(new Error("Request aborted"));
}
function onReqEnd() {
waitend = false;
}
function handleError(err) {
var first = !self.error;
if (first) {
self.error = err;
req.removeListener('aborted', onReqAborted);
req.removeListener('end', onReqEnd);
if (self.destStream) {
self.destStream.emit('error', err);
}
}
cleanupOpenFiles(self);
if (first) {
self.emit('error', err);
}
}
At first I thought this was the way the jqXHR request was aborted, but it seems to be a generic Skipper issue on aborted uploads, since the simple act of closing the tab during an upload will crash the server (different message):
_stream_writable.js:233
cb(er);
^
TypeError: object is not a function
at onwriteError (_stream_writable.js:233:5)
at onwrite (_stream_writable.js:253:5)
at WritableState.onwrite (_stream_writable.js:97:5)
at Writable.<anonymous> (.../node_modules/skipper-gridfs/index.js:179:25)
at Writable.g (events.js:180:16)
at Writable.EventEmitter.emit (events.js:117:20)
at PassThrough.<anonymous> (.../node_modules/skipper-gridfs/index.js:194:36)
at PassThrough.g (events.js:180:16)
at PassThrough.EventEmitter.emit (events.js:117:20)
at .../node_modules/sails/node_modules/skipper/standalone/Upstream/prototype.fatalIncomingError.js:55:17
I have tried aborting the upload by closing the tab while using a simple upload controller (not Skipper) and there is no crash:
var uploadFile = req.file('fileTest');
console.log(uploadFile);
uploadFile.upload(function onUploadComplete (err, files) { // Files will be uploaded to .tmp/uploads
if (err) return res.serverError(err); // IF ERROR Return and send 500 error with error
console.log(files);
res.json({status:200,file:files});
});
So, did anybody see this happening and is there any workaround?
This issue has been solved in skipper#0.5.4 and skipper-disk#0.5.4
Ref.: https://github.com/balderdashy/skipper/issues/49
Also there is an Issue in skipper-gridfs#0.5.3
Link: https://github.com/willhuang85/skipper-gridfs/issues/20