Return abitrary http code in symfony - symfony

Using symfony standard edition 2.6 and the FOSRestBundle, I'm throwing HttpException in my controller:
throw new HttpException(525, "An error occured", $e);
In the browser, it shows as an error 500.
When using 509 for instance, it's showing as 509.
What's wrong ?

It seems that it's a bug from symfony.
In the HttpKernel->handleException() method, only the status code is set:
if ($e instanceof HttpExceptionInterface) {
// keep the HTTP status code and headers
$response->setStatusCode($e->getStatusCode());
Then it tries to detect the statusText from the static array Response::$statusText but your code (530) is not defined, so it sets an empty text:
if (null === $text) {
$this->statusText = isset(self::$statusTexts[$code]) ? self::$statusTexts[$code] : '';
return $this;
}
if (false === $text) {
$this->statusText = '';
return $this;
}
I'm not sure that according to the from the RFC the statusText (== reapon-phrase) is mandatory: it seems that is can be a space, so HTTP/1.1 525 (with two space) should be valid.
I think that apache (or the apache php binding) is modifying the status code when no status text is provided.

Related

Create custom response in .NET Core 5 with OData 8 controller

I'm using OData 8 in .NET Core 5 with the [EnableQuery] attribute. Problem is when I want to return Problem() or BadRequest("Some message"), the API always returns some default OData BadRequest and never the message I wanted (only when [EnableQuery] attribute is there).
Example:
[HttpGet]
[EnableQuery(EnsureStableOrdering = false )]
public IActionResult GetList(ODataQueryOptions<List> queryOptions)
{
if (queryOptions.Filter == null)
{
return BadRequest( "Filter is required for this endpoind!" );
}
try
{
queryOptions.Filter.Validator = new OdataCustomFilterValidator();
this.BaseValidateQueryOptions(queryOptions);
}
catch (ODataException ex)
{
return this.BadRequest(ex.Message);
}
IQueryable<List> list = this._service.GetList();
return this.Ok(list);
}
So in the above example, if the code gets to the first IF, i do not recieve this message but ALWAYS the same Odata error:
{
"error": {
"code": "",
"message": "The query specified in the URI is not valid. The requested resource is not a collection. Query options $filter, $orderby, $count, $skip, and $top can be applied only on collections.",
"details": [],
Hi you ran into this bug which was fixed in OData/WebApi https://github.com/OData/WebApi/issues/2511 but it seems like it has not yet been migrated to AspNetCoreOData, A pull request exists which when merged and published should allow you to continue with your use case which is valid.

Status code 500 when deleting an object using axios and Symfony but deletion works

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;

Pipeline with parameters won't call

I have a pipeline with three optionals parameters when I try to call it with one parameter, I have an error message :
Suspected injection of control parameters in storefront request. Aborting request.
It is weird because I copy/paste from an existant pipeline which is working.
Thanks !
The ControlParameterInjectionDetector makes the following check:
public boolean isRequestLegal(String pipelineName, String startNodeName, Map<String, String[]> parameters)
{
if ((parameters.containsKey("PageletEntryPointUUID") || parameters.containsKey("PageletEntryPointID")) &&
!("ViewContent".equals(pipelineName) && "Start".equals(startNodeName)))
{
return false;
}
if (parameters.containsKey("WorkingTemplate"))
{
return false;
}
return true;
}

HowTo set response status code in CXF SOAP OneWay request on error

I have implemented a #OneWay JAX-RS service with Apache CXF ( a dropwizard application ). When called with invalid structure, causing an unmarshalling error in DocLiteralInInterceptor, http status code 200 is returned to client. To make the calling process recognize the fault, I need to return status 400 or 500, along with the error text from Unmarshalling Error.
I recognized that, after the error, the "in" interceptor chain is unwound ( interceptors handleFault-methods are called in reverse order ), so I installed an interceptor at the start of the "in"-chain ( last on unwinding ) with
public CustomSOAPInterceptor(String chainname) {
super(Phase.RECEIVE);
getBefore().add(PolicyInInterceptor.class.getName());
this.chainname=chainname;
}
Within my handleFault-Method I can seperate the fault message and recognize the unmarshall error. But I am not succeeding in setting the response.
I tried
Fault f = (Fault) e;
f.setStatusCode(Response.Status.BAD_REQUEST.getStatusCode());
and
Response response = Response
.status(Response.Status.BAD_REQUEST)
.entity(Response.Status.BAD_REQUEST.getStatusCode() + " " + f.getLocalizedMessage())
.build();
soapMessage.getExchange().put(Response.class, response);
and
message.put(Message.RESPONSE_CODE, Response.Status.BAD_REQUEST.getStatusCode());
Where is the response set and how can I overwrite it ?
Tx for any advice.
I know, its kind of late, but for those who are looking for a solution:
In my application, the following works:
public void handleFault(SoapMessage soapMessage) {
/* some code to test for specific error deleted */
Exchange exchange = soapMessage.getExchange();
Message outMessage = exchange.getOutMessage();
if (outMessage == null) {
Endpoint endpoint = exchange.get(Endpoint.class);
outMessage = endpoint.getBinding().createMessage();
exchange.setOutMessage(outMessage);
}
try {
EndpointReferenceType target = exchange.get(EndpointReferenceType.class);
Conduit conduit = exchange.getDestination().getBackChannel(soapMessage);
exchange.setConduit(conduit);
conduit.prepare(outMessage);
} catch (IOException ex) {
LOG.error(ex.getMessage(), ex);
}
Object resp = outMessage.get("HTTP.RESPONSE");
if (resp != null && resp instanceof HttpServletResponse) {
HttpServletResponse response = (HttpServletResponse) resp;
response.setStatus(Response.Status.BAD_REQUEST.getStatusCode());
}
soapMessage.getInterceptorChain().abort();
}

Triggering a fallback using #HystrixProperty timeout for HTTP status codes and other exceptions

I have a function in my #Service class that is marked with #HystrixCommand.
This method acts as a client which sends a request to another service URL and gets back a response.
What I want to do is to trigger a fallback function when the response status code is anything other than 200. It will also trigger a fallback for any other exceptions (RuntimeExceptions etc.).
I want to do this by making use of the #HystrixProperty or #HystrixCommandProperty.
I want the client to ping the URL and listen for a 200 response status and if it does not get back a 200 status within a certain time-frame I want it to fallback.
If it gets back a 200 status normally within a certain time it should not trigger the fallback.
#HystrixCommand(fallbackMethod="fallbackPerformOperation")
public Future<Object> performOperation(String requestString) throws InterruptedException
return new AsyncResult<Object>() {
#Override
public Object invoke() {
Client client = null;
WebResource webResource = null;
ClientResponse response =null;
String results = null;
try{
client = Client.create();
webResource = client.resource(URL);
client.setConnectTimeout(10000);
client.setReadTimeout(10000);
response = webResource.type("application/xml")
.post(ClientResponse.class, requestString);
} finally {
client.destroy();
webResource = null;
}
return results;
}
};
}
I specifically want to make use of the #HystrixProperty or #HystrixCommandProperty so performing a check inside the method for response status code not being 200 and then throwing an Exception is not acceptable.
Instead of using Annotations will creating my own Command by extending the HystrixCommand Interface work?
Any ideas or resources for where I can start with this are more than welcome.
I don’t understand why you don’t want to check the response http status code and throw an exception if it is not 200? Doing that will give you the behaviour you desire. i.e. it will trigger a fall back for exceptions or non 200 responses.
You can set the timeout in the client, however I would opt for using the hystrix timeout values. That way you can use Archaius to dynamically change the value at runtime if desired.
You can use the Hystrix command annotation or extend the HystrixCommand class. Both options will provide you with your desired behaviour
Here is an example using the annotation.
#HystrixCommand(fallbackMethod = "getRequestFallback")
public String performGetRequest(String uri) {
Client client = Client.create();
WebResource webResource = client.resource(uri);
ClientResponse response = webResource.get(ClientResponse.class);
if (response.getStatus() != 200) {
throw new RuntimeException("Invalid response status");
}
return response.getEntity(String.class);
}
public String getRequestFallback(String uri) {
return "Fallback Value";
}

Resources