I have the following problem.
I created a class to take care of all calls to a database.
I'm using RequestBuilder on the front end of GWT to send a HTTP GET request.
public String getDadosGET(String phpFilePath) {
rb = new RequestBuilder(RequestBuilder.GET, phpFilePath);
rb.setHeader(header, headerValue);
try {
response = rb.sendRequest(null, new RequestCallback() {
#Override
public void onResponseReceived(Request request, Response response) {
text = response.getText();
}
#Override
public void onError(Request request, Throwable exception) {
}
});
} catch (RequestException e) {
e.printStackTrace();
}
return text;
}
Now If I output the text inside the onResponseReceived method, It's not null.
If done right before return text, it's null.
What I need is to force the program to get the data first, then return the method.
Thanks.
I think you haven't quite understood the concept of asynchronous calls. Check out the this article.
I don't think there's a way of making a GWT call synchronously, which is what you seem to want.
Related
I'm trying to make an app when users fill form, and click send button, to send informations through url parametrs like :
localhost/my.php?param1=Name¶m2=SureName
I have read through internet about it, but can't get it, I found some examples but they tell how to pass through Json, I want just to send through link. (I think is easiest way )
My php code is:
<?php
require "connection.php";
if (!isset($_GET['param1'])) {
echo '<p align="center"> No data passed!</p>"';
}
if (strcmp($_GET['param1'],'FirstParam')== 0)
{
$sql= "Query HERE TO ADD INTO DB";
mysqli_query($connection,$sql);
if ($connection->query($sql) === TRUE) {
echo "Record updated successfully";
} else {
echo "Error updating record: " . $connection->error;
}
mysqli_close($connection);
}
Any help will be appreciated.
I recommend to have a look on OkHttp. It is an easy library to send HTTP requests in whatever way you like. On Vogella you can also find an example of sending a GET request with additional parameters. Basically it looks like this
HttpUrl.Builder urlBuilder = HttpUrl.parse("https://api.github.help").newBuilder();
urlBuilder.addQueryParameter("v", "1.0");
urlBuilder.addQueryParameter("user", "vogella");
String url = urlBuilder.build().toString();
Request request = new Request.Builder()
.url(url)
.build();
And after that you need to send your request (asynchronously) with the help of the OkHttpClient like this
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
#Override
public void onResponse(Call call, final Response response) throws IOException {
if (!response.isSuccessful()) {
throw new IOException("Unexpected code " + response);
} else {
// do something wih the result
}
}
(Code was taken from Vogella)
I've written some code in Laravel 5.2 to retrieve results from an unrelible API source. However, it needs to be able to automatically retry the request on failed attempts, as the API call results in a 503 about a third of the time.
I'm use Guzzle to do this, and I think I know where to put the code that will intercept the 503 responses before they are processed; but I'm not sure what to actually write there.
The guzzle documentation doesn't offer much as far as retries go, and all of the examples I've come across of Guzzle 6 only show how to retrieve results (which I can already do), but not how to get it to repeat the request if needed.
I'm by no means asking anyone to do the work for me - but I think I'm approaching the limits of my understanding on this. If anybody can point me in the right direction, it'd be much appreciated :)
EDIT:
I will try and revise. Please consider the following code. In it, I want to send a GET request which should normally yield a JSON response.
DataController.php
$client = new \GuzzleHttp\Client();
$request = $client->request('GET', 'https://httpbin.org/status/503'); // URI is for testing purposes
When the response from this request is a 503, I can intercept it here:
Handler.php
public function render($request, Exception $e)
{
if ($e->getCode() == 503)
{
// Code that would tell Guzzle to retry the request 5 times with a 10s delay before failing completely
}
return parent::render($request, $e);
}
I don't know that that is the best place to put it, but the real problem is I don't know is what to write inside the if ($e->getCode() == 503)
Guzzle by default throws exceptions when a non 2** response is returned. In your case you're seeing a 503 response. Exceptions can be thought of as errors that the application can recover from. The way this works is with try catch blocks.
try {
// The code that can throw an exception will go here
throw new \Exception('A generic error');
// code from here down won't be executed, because the exception was thrown.
} catch (\Exception $e) {
// Handle the exception in the best manner possible.
}
You wrap the code that could throw an exception in the try portion of the block. Then you add your error handling code in the catch portion of the block. You can read the above link for more information on how php handles exceptions.
For your case, lets move the Guzzle call to it's own method in your controller:
public function performLookUp($retryOnError = false)
{
try {
$client = new \GuzzleHttp\Client();
$request = $client->request('GET', 'https://httpbin.org/status/503');
return $request->send();
} catch (\GuzzleHttp\Exception\BadResponseException $e) {
if ($retryOnError) {
return $this->performLookUp();
}
abort(503);
}
}
Now in your controller you can execute, $this->performLookUp(true);.
Just to add some information to clarify a few points that Logan made.
Guzzle "can" throw exceptions on a Response other then 2**/3**. It all depends upon how the GuzzleHttp\HandlerStack is created.
$stack = GuzzleHttp\HandlerStack::create();
$client = new Client(['handler'=> $stack]);
$client = new Client();
// These two methods of generating a client are functionally the same.
$stack = New GuzzleHttp\HandlerStack(new GuzzleHttp\Handler\CurlHandler());
$client = new Client(['handler'=> $stack]);
// This client will not throw exceptions, or perform any of the functions mentioned below.
The create method adds default handlers to the HandlerStack. When the HandlerStack is resolved, the handlers will execute in the following order:
Sending request:
http_errors - No op when sending a request. The response status code is checked in the response processing when returning a response promise up the stack.
allow_redirects - No op when sending a request. Following redirects occurs when a response promise is being returned up the stack.
cookies - Adds cookies to requests.
prepare_body - The body of an HTTP request will be prepared (e.g., add default headers like Content-Length, Content-Type, etc.).
send request with handler
Processing response:
prepare_body - no op on response processing.
cookies - extracts response cookies into the cookie jar.
allow_redirects - Follows redirects.
4.http_errors - throws exceptions when the response status code >= 300.
When provided no $handler argument, GuzzleHttp\HandlerStack::create() will choose the most appropriate handler based on the extensions available on your system. As indicated within the Handler Documentation
By manually creating your GuzzleHttp\HandlerStack, you can add middleware to the application. Given the context of your original question "how do i repeat the request" I believe you are most interested in the Retry Middleware that is provided within Guzzle 6.1. This is a middleware that retries requests based on the result of the provided decision function.
Documentation has yet to catch up with this class.
final class HttpClient extends \GuzzleHttp\Client
{
public const SUCCESS_CODE = 200;
private int $attemptsCount = 3;
private function __construct(array $config = [])
{
parent::__construct($config);
}
public static function new(array $config = []): self
{
return new self($config);
}
public function postWithRetry(string $uri, array $options = []): Response
{
$attemptsCount = 0;
$result = null;
do {
$attemptsCount++;
$isEnd = $attemptsCount === $this->attemptsCount;
try {
$result = $this->post(
$uri,
$options,
);
} catch (ClientException $e) {
$result = $e->getResponse();
} catch (GuzzleException $e) {
if ($isEnd) {
Logger::error($e->getMessage());
$result = $e->getResponse();
}
}
} while ($this->isNeedRetry($result, $attemptsCount));
return $result;
}
private function isNeedRetry(?Response $response, int $attemptsCount): bool
{
return $response === null && $attemptsCount < $this->attemptsCount;
}
I'm new to PHPUnit and Selenium, and I want to test a 'remove' button by confirming that an element with a given ID exists before the button is clicked, but no longer exists after the button is clicked.
If I use something like this to check that the element has been deleted:
$this->assertFalse($this->byId('idRemoved'));
Then I get a test failure in byId() because it can't find idRemoved (which is true, because it's not there.)
How can I test for the lack of an element, so the test fails if idRemoved is found?
This is what I ended up using, thanks to Karna's suggestion. I'm posting it as another answer as I am using PHP, so for the benefit of anyone else using PHPUnit and Selenium, here is a similar method to Karna's, but for PHPUnit:
try {
$this->byId('idRemoved');
$this->fail('The element was not deleted.');
} catch (PHPUnit_Extensions_Selenium2TestCase_WebDriverException $e) {
$this->assertEquals(PHPUnit_Extensions_Selenium2TestCase_WebDriverException::NoSuchElement, $e->getCode());
}
The code was taken from line 1070 in the PHPUnit Selenium test code, which I found after Karna pointed me in the right direction.
For those arriving late at the party: a better solution would be to create your own expected condition class and extend the Facebook\WebDriver\WebDriverExpectedCondition to write your own method:
public function elementNotPresent(WebDriverBy $by)
{
return new static(
function (WebDriver $driver) use ($by) {
try {
$driver->findElement($by);
return false;
} catch (Exception $e) {
return true;
}
}
);
}
Update: The above is intended for Facebook's Selenium WebDriver bindings for PHP
Java equivalent will be
public boolean isElementExists(By by) {
boolean isExists = true;
try {
driver.findElement(by);
} catch (NoSuchElementException e) {
isExists = false;
}
return isExists;
}
You can assert that a specific exception gets thrown if you'd like:
/**
* #expectedException MyException
* #expectedExceptionMessage Some Message
*/
public function testExceptionHasRightMessage()
{
//yourCodeThatThrows new MyException('Some Message')
}
I have php code that execute python cgi and I want to pass python trace (returned from cgi) as extra data to php exception how can I do this and how can I get that value from catch(Exception e) { (It should check if that extra value exesit or not).
I have code like this:
$response = json_decode(curl_exec($ch));
if (isset($response->error)) {
// how to send $response->trace with exception.
throw new Exception($response->error);
}
return $response->result;
and I use json-rpc library that should return that data to the user:
} catch (Exception $e) {
//catch all exeption from user code
$msg = $e->getMessage();
echo response(null, $id, array("code"=>200, "message"=>$msg));
}
Do I need to write new type of exception or can I do this with normal Exception? I would like to send everything that was thrown in "data" =>
You need to extend Exception class:
<?php
class ResponseException extends Exception
{
private $_data = '';
public function __construct($message, $data)
{
$this->_data = $data;
parent::__construct($message);
}
public function getData()
{
return $this->_data;
}
}
When throwing:
<?php
...
throw new ResponseException($response->error, $someData);
...
And when catching:
catch(ResponseException $e) {
...
$data = $e->getData();
...
}
Dynamic Property (not recommended)
Please note that this will cause deprecation error in PHP 8.2 and will stop working in PHP 9 according to one of the PHP RFC https://wiki.php.net/rfc/deprecate_dynamic_properties
As the OP asking about doing this task without extending Exception class, you can totally skip ResponseException class declaration. I really not recommend do it this way, unless you've got really strong reason (see this topic for more details: https://softwareengineering.stackexchange.com/questions/186439/is-declaring-fields-on-classes-actually-harmful-in-php)
In throwing section:
...
$e = new Exception('Exception message');
$e->data = $customData; // we're creating object property on the fly
throw $e;
...
and when catching:
catch(Exception $e) {
$data = $e->data; // Access data property
}
September 2018 edit:
As some of readers found this answer useful, I have added a link to another Stack Overflow question which explains the downsides of using dynamically declared properties.
Currently, your code converts the response text directly into an object without any intermediate step. Instead, you could always just keep the serialized (via JSON) text it and append it to the end of the Exception message.
$responseText = curl_exec($ch);
$response = json_decode($responseText);
if (isset($response->error)) {
throw new Exception('Error when fetching resource. Response:'.$responseText);
}
return $response->result;
Then you could just recover everything after "Response:" in your error log and optionally de-serialize it or just read it.
As an aside, I would also not count on the server sending JSON, you should verify that the response text was actually parseable as JSON and return a separate error for that if it isn't.
my api controller:
$POST /api/member/logout
public function post_logout(){
try{
member::logout();
return Response::json([], 200);
}catch(Exception $e){
print_r($e);
return Response::json($e, 500);
}
}
and my model
public static function logout(){
if(!Auth::check()){
throw new Exception('not_logged');
}
Auth::logout();
}
It is returning status 200 but never ends loading (18.3mb loaded and counting...)
You are printing Exception object before json response with status 500, so PHP automatically sends response with status code 200.
As for huge never-ending response, I'm not sure since I don't know Laravael at all, but I suspect, that somewhere you are (or this framework is) dumping an object that references itself.