Pass extra parameters to silex error handler callback function - silex

I'm building an app with Silex and Twig where I have my route handlers defined in this way (standard way):
//routes.php
$app->get('/pageA',function () use($app){
//Display something
});
$app->get('/pageB',function () use($app){
//Display something
});
$app->post('/pageB',function (Request $req) use($app){
//Process something
});
And then I have set up an error handler to manager possible errors that are thrown inside the route handlers, like this:
//routes.php
$app->post('/pageB',function (Request $req) use($app){
//Do something, but an error occurs..
$app->abort(404,"Page not found");
});
//errors.php
$app->error(function (\Exception $e, $code) use($app) {
switch($code){
case 404:
return $app['twig']->render('404.twig',array('error'=>$e->getMessage()));
//Other error codes...
default:
//return something
}
});
What I would like to do is pass an extra parameter from the route handler to the callback function of the error handler, like this:
//routes.php
$app->post('/pageB',function (Request $req) use($app){
//Do something, but an error occurs..
$app->abort(404,"Page not found","My extra parameter");
});
//errors.php
$app->error(function (\Exception $e, $code,$extra_param=null) use($app) {
if(isset($extra_param))
//Process the error in a different way
else{ //Standard way
switch($code){
case 404:
return $app['twig']->render('404.twig',array('error'=>$e->getMessage()));
//Other error codes...
default:
//return something
}
}
});
Can this be done?

This might not be the most elegant solution but you could probably just add an array to $app.
$app['my_param_bag'] = array();
$app->get('/pageB', function(Request $request) use ($app) {
$app['my_param_bag'] = array('foo', 'bar', 'baz');
$app->abort(404, "Page not found");
});
$app->error(function (\Exception $e, $code) use($app) {
error_log(print_r($app['my_param_bag'],1).' '.__FILE__.' '.__LINE__,0);
if(!empty($app['my_param_bag'])) {
// do something with the params
}
else{
switch($code){
case 404:
return $app['twig']->render('404.html.twig',array('error'=>$e->getMessage()));
default:
}
}
});
I'm not sure about how you have your application setup but for me I was able to add this empty array in a configuration file.

Related

Manifest v3 extension: asynchronous event listener does not keep the service worker alive [duplicate]

I am trying to pass messages between content script and the extension
Here is what I have in content-script
chrome.runtime.sendMessage({type: "getUrls"}, function(response) {
console.log(response)
});
And in the background script I have
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
if (request.type == "getUrls"){
getUrls(request, sender, sendResponse)
}
});
function getUrls(request, sender, sendResponse){
var resp = sendResponse;
$.ajax({
url: "http://localhost:3000/urls",
method: 'GET',
success: function(d){
resp({urls: d})
}
});
}
Now if I send the response before the ajax call in the getUrls function, the response is sent successfully, but in the success method of the ajax call when I send the response it doesn't send it, when I go into debugging I can see that the port is null inside the code for sendResponse function.
From the documentation for chrome.runtime.onMessage.addListener:
This function becomes invalid when the event listener returns, unless you return true from the event listener to indicate you wish to send a response asynchronously (this will keep the message channel open to the other end until sendResponse is called).
So you just need to add return true; after the call to getUrls to indicate that you'll call the response function asynchronously.
The accepted answer is correct, I just wanted to add sample code that simplifies this.
The problem is that the API (in my view) is not well designed because it forces us developers to know if a particular message will be handled async or not. If you handle many different messages this becomes an impossible task because you never know if deep down some function a passed-in sendResponse will be called async or not.
Consider this:
chrome.extension.onMessage.addListener(function (request, sender, sendResponseParam) {
if (request.method == "method1") {
handleMethod1(sendResponse);
}
How can I know if deep down handleMethod1 the call will be async or not? How can someone that modifies handleMethod1 knows that it will break a caller by introducing something async?
My solution is this:
chrome.extension.onMessage.addListener(function (request, sender, sendResponseParam) {
var responseStatus = { bCalled: false };
function sendResponse(obj) { //dummy wrapper to deal with exceptions and detect async
try {
sendResponseParam(obj);
} catch (e) {
//error handling
}
responseStatus.bCalled= true;
}
if (request.method == "method1") {
handleMethod1(sendResponse);
}
else if (request.method == "method2") {
handleMethod2(sendResponse);
}
...
if (!responseStatus.bCalled) { //if its set, the call wasn't async, else it is.
return true;
}
});
This automatically handles the return value, regardless of how you choose to handle the message. Note that this assumes that you never forget to call the response function. Also note that chromium could have automated this for us, I don't see why they didn't.
You can use my library https://github.com/lawlietmester/webextension to make this work in both Chrome and FF with Firefox way without callbacks.
Your code will look like:
Browser.runtime.onMessage.addListener( request => new Promise( resolve => {
if( !request || typeof request !== 'object' || request.type !== "getUrls" ) return;
$.ajax({
'url': "http://localhost:3000/urls",
'method': 'GET'
}).then( urls => { resolve({ urls }); });
}) );

how to combine multiple instances of navigator.serviceWorker.register('sw.js')

for example in my index.html I have a code to detect an update for service worker and the code is like this:
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('sw.js').then(reg => {
reg.addEventListener('updatefound', () => {
// A wild service worker has appeared in reg.installing!
newWorker = reg.installing;
newWorker.addEventListener('statechange', () => {
// Has network.state changed?
switch (newWorker.state) {
case 'installed':
if (navigator.serviceWorker.controller) {
// new update available
showUpdateBar();
}
// No update available
break;
}
});
});
});
let refreshing;
navigator.serviceWorker.addEventListener('controllerchange', function () {
if (refreshing) return;
window.location.reload();
refreshing = true;
});
}
then in pushManager.js the code is like:
navigator.serviceWorker.register('sw.js')
.then(function (registration) {
messaging.useServiceWorker(registration);
// Request for permission
messaging.requestPermission()
.then(function() {
console.log('Notification permission granted.');
// TODO(developer): Retrieve an Instance ID token for use with FCM.
messaging.getToken()
.then(function(currentToken) {
if (currentToken) {
console.log('Token: ' + currentToken)
sendTokenToServer(currentToken);
// updateSubscriptionOnServer(currentToken);
} else {
console.log('No Instance ID token available. Request permission to generate one.');
setTokenSentToServer(false);
}
})
......
The pushManagr.js is included in both login/index.html and index.html.
I think that calling navigator.serviceWorker.register at multiple places will have adverse effect.
so how I can combine the two instances into one.
If possible, remove the registration of the serviceworker from pushManager.
If you want the registration instance of the serviceworker,use the api getRegistration()
navigator.serviceWorker.getRegistration(/*scope*/).then(function(registration) {
if(registration){
// Move all your firebase messaging code to here
messaging.useServiceWorker(registration);
}
});

How to handle FileSystemException in dart when watching a directory

I have written a simple command line tool in dart that watches changes in a directory if a directory does not exits I get FileSystemsException.
I have tried to handle it using try and catch clause. When the exception occurs the code in catch clause is not executed
try {
watcher.events.listen((event) {
if (event.type == ChangeType.ADD) {
print("THE FILE WAS ADDED");
print(event.path);
} else if (event.type == ChangeType.MODIFY) {
print("THE FILE WAS MODIFIED");
print(event.path);
} else {
print("THE FILE WAS REMOVED");
print(event.path);
}
});
} on FileSystemException {
print("Exception Occurs");
}
I expect the console to print "Exception Occurs"
There are two possibilities:
The exception is happening outside this block (maybe where the watcher is constructed?)
The exception is an unhandled async exception. This might be coming from either the Stream or it might be getting fired from some other Future, like perhaps the ready Future.
You can add handlers for the async exceptions like this:
try {
// If this is in an `async` method, use `await` within the try block
await watcher.ready;
// Otherwise add a error handler on the Future
watcher.ready.catchError((e) {
print('Exception in the ready Future');
});
watcher.events.listen((event) {
...
}, onError: (e) {
print('Exception in the Stream');
});
} on FileSystemException {
print("Exception Occurs");
}
My guess would be it's an error surfaced through the ready Future.

How to make AngularJS throw error instead of silently failing when template cannot be retrieved? [duplicate]

In an AngularJS directive the templateUrl parameter is defined dinamically.
'templates/' + content_id + '.html'
I don't want to establish rules to check if content_id value is valid and manage it as 404 errors, i.e. if the template doesn't exist (server return a 404 error when loading the template) load template/404.html instead.
How can I do that?
Edited: The current answers suggest to use a response error interceptor. In this case ¿how can I know that the response is to a loading of this template?
You will need to write response error interceptor. Something like this:
app.factory('template404Interceptor', function($injector) {
return {
responseError: function(response) {
if (response.status === 404 && /\.html$/.test(response.config.url)) {
response.config.url = '404.html';
return $injector.get('$http')(response.config);
}
return $q.reject(response);
}
};
});
app.config(function($httpProvider) {
$httpProvider.interceptors.push('template404Interceptor');
});
Demo: http://plnkr.co/edit/uCpnT5n0PkWO53PVQmvR?p=preview
You can create an interceptor to monitor all requests made with the $http service and intercept any response errors. If you get a status 404 for any request made, simply redirect the user to error page(template/404.html in your case).
.factory('httpRequestInterceptor', function ($q) {
return {
'responseError': function(rejection) {
if(rejection.status === 404){
// do something on error
}
}
return $q.reject(rejection);
}
};
});
You would need to push the interceptor to $httpProvider in your config function.
myApp.config( function ($httpProvider, $interpolateProvider, $routeProvider) {
$httpProvider.interceptors.push('httpRequestInterceptor');
});
Here's the demo
Cheers!

Checking success, error and complete statuses in ajax script

I have below script in asp.net mvc:
$.ajax({
url: "/MyController/MyAction/",
type: 'POST',
data: $("#Myform").serialize(),
success: function () {
// Do something
},
error: function () {
// Do something
},
complete: function () {
// Do something
},
beforeSend: function () {
// Do someting
}
});
This script calls to an action in the controller. The controller performs some actions and sometimes things go ok or not. If things went ok, I want success and complete options in the script get executed.No problem until here, but if in the controller there is an error or something I want to tell the script: "hey, there is an error!" and then the error option in the script to be executed. How to do this? Do I have to return something from the controller to the script to indicate an error has been generated in order to error option in the script gets executed?
Set the HTTP status code to 4xx or 5xx in the controller.
That will make you end up in the error callback.
As far as the AJAX request goes an error is an transfer/network error getting the page.
If you want to return an error either return it in the data then parse that and execute the error function inside the success part if you detect an error. Or as, Johan says, return an HTTP error code from the server.
Use try catch in your action like,
public ActionResult Sample()
{
try
{
return Json(new{status="success"},JsonRequestBehavior.AllowGet);
}
catch(Exception ex)
{
return Json(new{status="failed"},JsonRequestBehavior.AllowGet);
}
}
In your ajax call success check with condition like,
if(data.status=='success')
{
alert('All Happies');
}
else
{
alert('error came');
}
Hope this helps.

Resources