I have a problem with Symfony2 duplicating requests.
The example controller below should just return a transparent gif. However, when the URL is requested there are two 'hits' to the request and doSomething() is called twice instead of once.
// simple action in a controller, ends up being called twice
public function testAction() {
doSomething();
$response = new Response(base64_decode('R0lGODlhAQABAIAAAOrq6gAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='));
$response->headers->set('Content-Type', 'image/gif');
return $response;
}
If I change the response line so it sets a blank response then this stops happening (i.e. doSomething() is only called once):
// with a blank response it is only called once
public function testAction() {
doSomething();
$response = new Response('');
$response->headers->set('Content-Type', 'image/gif');
return $response;
}
If I remove the headers line then it's only called once:
// without the Content-Type header it is only called once
public function testAction() {
doSomething();
$response = new Response(base64_decode('R0lGODlhAQABAIAAAOrq6gAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='));
return $response;
}
Finally (here's the punchline)... if I change the Content-Type to text/html (or text/css) then it is only called once!
// if a text content type is used, it is only called once
public function testAction() {
doSomething();
$response = new Response(base64_decode('R0lGODlhAQABAIAAAOrq6gAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='));
$response->headers->set('Content-Type', 'text/html');
return $response;
}
But with real content and the proper headers it is called twice (and two identical looking entries appear in the web profiler). The same problem also happens if a php template is used to render the content (I haven't tried with twig).
What could be causing this and how can it be prevented (or worked around)?
Edit: So, in summary, it was a Firefox bug and nothing to do with Symfony at all.
Related
I'm using vue as my frontend. I want to delete an object from my database when a button is pressed, I post the selected object with axios but I get the following error:
wish.js:40 Error: Request failed with status code 500
at createError (createError.js:16)
at settle (settle.js:17)
at XMLHttpRequest.handleLoad (xhr.js:61)
even though my object does get deleted from my database.
Here is my code:
postWishToBeDeleted({commit}, wishId) {
console.log(wishId);
axios.post('/api/post/delete', {
wishId: wishId
}).catch(error => {
console.error(error);
}).then( response => {
commit('removeWish', wishId);
}
)
}
Inside my symfony controller:
/**
* #Route("/api/post/delete", name="app_api_post_delete", methods={"POST"})
*/
public function deleteWish(Request $request, WishRepository $repository) {
$data = $request->getContent();
$data = json_decode($data, true);
$wish = $repository->find($data['wishId']);
$em = $this->getDoctrine()->getManager();
$em->remove($wish);
$em->flush();
return $this->json($wish);
}
I think that something with my response is wrong, I'm still new to Vue and axios so I'm not sure how return the json object correctly
EDIT:
I noticed that this error only occurs if I have more than one object?? If I it's only one and I delete it, there's no error
Status 500 is a server error, and it sounds from the behavior that whatever causes the error must happen after the item is removed.
Looking at the deleteWish method, if $wish has been removed, maybe the problem is trying to convert it to JSON when it's undefined. Try to return something else like:
return true;
I have a controller that response a json data to another application , this is the controller code :
/**
*
* #Get("/getXXX/{id}")
*/
public function getDataAction($id,Request $request){
$ceService = $this->container->get('comptexpertcews.service');
$employeNumber= $request->get('employeNumber') ;
$url = $this->container->getParameter('serverUri') . $id;
$res = new Response();
$res->setContent($ceService->getCews($url, wsUrl::ws_Headers));
$res->headers->set('Content-TYpe','application/json; charset=UTF-8');
return $res;
}
The problem is by default , if you don't give id in the url , symfony rise exception : not route foundexception , what i want is to handle the exception and personalize with my owner response like sending
{"error" :" id undefined "}
instead of the long message expcetion of symfony
You have two simple options:
Don't use param converter, get you data from a repository and then you can wrap it in try catch and create your own exception/message
If this is something you want to do globally, you can implement an event listener that catches onKernelException event and work with it from there, e.g.:
public function onKernelException(GetResponseForExceptionEvent $event): void
{
$exception = $event->getException();
if ($exception instanceof NotFoundHttpException) {
$response = $this->resourceNotFoundResponse(json_encode($exception->getMessage()));
}
if (isset($response)) {
$event->setResponse($response);
}
}
You also need to register you listener as a service, see the documentation here http://symfony.com/doc/current/event_dispatcher.html
I am trying to set up a error handler on my controller to catch anything that might cause my page to malfunction. For example: in this scenario I am trying to catch any error that could possibly happen once my method calls a external API with a bad parameter but it doesn't seem to do anything except give me the typical ClientException in Middleware.php line 69:
Client error: 400 which isn't what I am exactly aiming for. Any advice will be greatly be appreciated or better ways of handling errors in Silex.
private function getSIS($url, $session, Application $app)
{
$message = "You don't have permission to access this!";
if($app['security']->isGranted('ROLE_SUPER_ADMIN'))
{
$client = new Client(['base_uri' => 'https://***********.ca/api/SIS/']);
if (!empty($session))
$response = $client->get($url, ['query' => 'session=' . $session]);
else
$response = $client->get($url);
return $response;
}
$app->error(function (\Exception $e, $code) {
switch($code) {
case 404:
$message = 'The requested page could not be found';
break;
default:
$message = 'We are sorry, but something went terribly wrong.';
}
return new Response($message);
});
return new Response($message);
}
The $app->error method might need to be placed outside the context of your controller actions. I'm not sure exactly how you have your application structured but maybe try placing the error block right before $app->run();
$app->error(function (\Exception $e, $code) use ($app) {
switch($code) {
case 404:
$message = 'The requested page could not be found';
break;
default:
$message = 'We are sorry, but something went terribly wrong.';
}
return new Response($message, $code);
});
$app->run();
I want to send response to the client which should include some details in header which is common, let say userID and others datails in the body. How to add such new parameters to header of response,
I tried,
public function postAPIAction()
{
$jsonData = $this->getRequest()->getContent();
$decodePostRequest = json_decode($jsonData, true);
// processing is involved........
$uniqueKey=$this->generateUniqueKey();
$response = new Response();
$response->headers->add(array('userId' => $uniqueKey));
return new Response(json_encode(array('errorcode' => '1'), true));
}
which is not working.
You have to return the response you've set the headers on instead of creating a new one in the return statement.
You're creating a new response in your return.
You should use the response you created before.
$response = new Response();
$response->headers->add(array('userId' => $uniqueKey));
$response->setContent(...);
return $response;
I am posting a form with Ajax.
I have a surprising response when binding a form within an Ajax call:
public function newCartAjaxAction(Request $request)
{
$form = $this->container->get('new_cart_form.factory')->create();
$formHandler = $this->container->get('new_cart_form.handler');
if ('POST' === $request->getMethod())
{
$form->bind($request);
if ($form->isValid())
{
$formHandler->processValidForm($form);
$response = new Response();
$response->headers->set('Content-type', 'application/json; charset=utf-8');
$response->setContent(json_encode('hello'));
return $response;
}
//...
}
//....
}
Using firebug, I surprisingly obtain 3 outputs in the ajax Response:
array(2) {[0]=>int(3)[1]=>int(5)} //unexpected response
int(3) //unexpected response
"hello" //The only response needed
After debugging, I figured out that output 1 and 2 are from $form->bind($request);
Does anyone know why that is? I am very surprised to obtain a response from the form binding step as the only response that I am supposed to send is $response...
Have I done something wrong?
It's likely that these outputs were caused by code you've written.
First, make sure that your vendors are clean by reinstalling them.
Then, it could also be a form event listener/subscriber that you've written, so have also a look in this way.