doing something after Laravel's http client exception - laravel

I need to access to an online file and reading is content, but if for some reason the file isn't available due network/server problem ill use a local version stored on my server.
For doing that I've written this simple code:
$response = Http::timeout(2)->get('http.site/file.json');
And I add this for checking if all is ok:
if($response->successful()){
$list = $response->body();
} else {
$list = file_get_contents(asset('storage/list.json'));
}
But if I have a problem (for testing I just add a not correct address) of connection an exception is thrown and I cannot go into "else" part.
So I add a "try, catch":
try{
$response = Http::timeout(2)->get('http.site/file.json');
return $response->body();
}catch (Exception $ex) {
return file_get_contents(asset('storage/pharmaciesList.json'));
}
which is the correct way to treat this kind of code, and is it correct using a try catch without taking care of the exception?

Of course it's the right way, every function that could throw an exception should be enclosed in a try catch block. Otherwise (you said you're using Laravel) you can handle that exception in the exception handler.

Related

Unable to catch error in laravel using try catch

I wrote a code to try and catch error.
I want that if the error occurs then laravel continues to the next one and i write the error in the error file as shown here.
Laravel's black page of error pops up which shows "ErrorException (E_WARNING) followed by the whole error on the left page and the programme is abruptly stopped.
Is there a way to skip the error notification which brings my whole code to a stop.
My attempt at coding to catch the error is here:
try {
$jsondata_car = (file_get_contents($urltofind_car));
} catch (Exception $e) {
$errorfile = fopen("errors", 'a');
fwrite($errorfile, $e - > getmessage().
"\n");
$failed_car = 9999999;
report($e);
return false;
}
Am I missing out something?
The error I get is here
file_get_contents(): failed to open stream:
HTTP request failed! HTTP/1.1 400 Bad Request
The error is shown on the line
$jsondata_car = (file_get_contents($urltofind_car));
The solution is here
Exception is used which should have contained a namespace.
The problem is that this does not throw up an error even though I had not written
Use Exception;
at the beginning.
As suggested by #simon R I made the rectification and it worked.
It is most likely still throwing the error because you haven't imported the Exception class
Ensure you either add
Use Exception;
to your class.
Alternative update your code to namespace it;
try {
$jsondata_car = (file_get_contents($urltofind_car));
} catch (\Exception $e) {
$errorfile = fopen("errors", 'a');
fwrite($errorfile, $e - > getmessage().
"\n");
$failed_car = 9999999;
report($e);
return false;
}

JUnit needs special permissions?

My builds have been failing due to some of the integration tests I've been running. I'm stuck on why it won't work. Here is an example of the output:
I'm using Maven to first build, then it calls the JUnit tests. I'm seeing this 401 Unauthorized message in every single test, and I believe that's what is causing the builds to fail. In my mind, this means there are some permissions / authentication parameters that need to be set. Where would I go about doing this in JUnit?
Edit
#Test
public void testXmlHorsesNonRunners() throws Exception {
String servletUrl = SERVER + "sd/date/2013-01-13/horses/nonrunners";
Document results = issueRequest(servletUrl, APPLICATION_XML, false);
assertNotNull(results);
// debugDocument(results, "NonRunners");
String count = getXPathStringValue(
"string(count(hrdg:data/hrdg:meeting/hrdg:event/hrdg:nonrunner/hrdg:selection))",
results);
assertEquals("non runners", "45", count);
}
If you can, try to ignore the detail. Effectively, this is making a request. This is a sample of a test that uses the issueRequest method. This method is what makes HTTP requests. (This is a big method, which is why I didn't post it originally. I'll try to make it as readable as possible.
logger.info("Sending request: " + servletUrl);
HttpGet httpGet = null;
// InputStream is = null;
DefaultHttpClient httpclient = null;
try {
httpclient = new DefaultHttpClient();
doFormLogin(httpclient, servletUrl, acceptMime, isIrishUser);
httpGet = new HttpGet(servletUrl);
httpGet.addHeader("accept", acceptMime);
// but more importantly now add the user agent header
setUserAgent(httpGet, acceptMime);
logger.info("executing request" + httpGet.getRequestLine());
// Execute the request
HttpResponse response = httpclient.execute(httpGet);
// Examine the response status
StatusLine statusLine = response.getStatusLine();
logger.info(statusLine);
switch (statusLine.getStatusCode()) {
case 401:
throw new HttpResponseException(statusLine.getStatusCode(),
"Unauthorized");
case 403:
throw new HttpResponseException(statusLine.getStatusCode(),
"Forbidden");
case 404:
throw new HttpResponseException(statusLine.getStatusCode(),
"Not Found");
default:
if (300 < statusLine.getStatusCode()) {
throw new HttpResponseException(statusLine.getStatusCode(),
"Unexpected Error");
}
}
// Get hold of the response entity
HttpEntity entity = response.getEntity();
Document doc = null;
if (entity != null) {
InputStream instream = entity.getContent();
try {
// debugContent(instream);
doc = documentBuilder.parse(instream);
} catch (IOException ex) {
// In case of an IOException the connection will be released
// back to the connection manager automatically
throw ex;
} catch (RuntimeException ex) {
// In case of an unexpected exception you may want to abort
// the HTTP request in order to shut down the underlying
// connection and release it back to the connection manager.
httpGet.abort();
throw ex;
} finally {
// Closing the input stream will trigger connection release
instream.close();
}
}
return doc;
} finally {
// Release the connection.
closeConnection(httpclient);
}
I notice that your test output shows HTTP/1.1 500 Internal Server Error a couple of lines before the 401 error. I wonder if the root cause could be hiding in there. If I were you I'd try looking for more details about what error happened on the server at that point in the test, to see if it could be responsible for the authentication problem (maybe the failure is in a login controller of some sort, or is causing a session to be cancelled?)
Alternately: it looks like you're using the Apache HttpClient library to do the request, inside the issueRequest method. If you need to include authentication credentials in the request, that would be the code you'd need to change. Here's an example of doing HTTP Basic authentication in HttpClient, if that helps. (And more examples, if that one doesn't.)
(I'd second the observation that this problem probably isn't specific to JUnit. If you need to do more research, I'd suggest learning more about HttpClient, and about what this app expects the browser to send. One possibility: use something like Chrome Dev Tools to peek at your communications with the server when you do this manually, and see if there's anything important that the test isn't doing, or is doing differently.
Once you've figured out how to login, it might make sense to do it in a #Before method in your JUnit test.)
HTTP permission denied has nothing to do with JUnit. You probably need to set your credentials while making the request in the code itself. Show us some code.
Also, unit testing is not really meant to access the internet. Its purpose is for testing small, concise parts of your code which shouldn't rely on any external factors. Integration tests should cover that.
If you can, try to mock your network requests using EasyMock or PowerMock and make them return a resource you would load from your local resources folder (e.g. test/resources).

login page automatically redirects to else case

this code shud check login credentials and forward either to logged in page for admin when getParameter(7)=1 or to customer when it is 0..
if login credentials are not correct it will go to error messages and fromt her to login page again.. but somehow it is directly going to errorpage in else case if its not admin!! next two cases are not being checked at all!!
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try
{
Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/mutualfund", "root", "");
Statement stmt = con.createStatement();
ResultSet result = stmt.executeQuery("SELECT * FROM login_table;");
String uname= request.getParameter("username");
String pass= request.getParameter("password");
while(result.next())
{
if(result.getString(1).equals(uname) && result.getString(2).equals(pass))
{
if(result.getBoolean(7)==true)
{
response.sendRedirect("displayFunds.jsp");
}
if((result.getBoolean(7)==false) && (result.getString(4).equals("")))
{
response.sendRedirect("changePassword.jsp?name="+uname+"&&pass="+pass);
}
if((result.getBoolean(7)==false) && (!result.getString(4).equals("")))
{
response.sendRedirect("custProfile.jsp");
}
}
else
{
response.sendRedirect("loginFailed.jsp");
}
}
}
catch (Exception ex) {
Logger.getLogger(Admin.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
You're not returning from the method, but continuing to iterate through the while loop. You seem to expect that a simple method call response.sendRedirect() magically aborts the whole while loop and returns from the method. It doesn't do that. The code just continues the loop, checking the next user and setting the redirect URL, hereby overriding the previous one.
You need to return from the method yourself.
response.sendRedirect(someURL);
return;
Your concrete problem is caused because your login doesn't match the last user entry in the DB.
Unrelated to the concrete problem, this approach is however terribly inefficient. You're not taking benefit of the powers of a relational database and instead copying the entire DB table into Java's memory and performing the comparison in Java. You should be writing SQL queries in such way that it returns exactly the information you need. In this particular case, you should be using the SQL WHERE clause instead (in a prepared statement!), so that the resultset contains exactly zero or one row.
if (resultSet.next()) {
// Login OK!
} else {
// Login fail!
}
Further, your code is also leaking DB resources by never closing them. You should be closing them in finally. Also, loading the JDBC driver on every HTTP request is unnecessary. Just load it once during webapp's/servlet's startup.
See also:
Login works only for last user in the database
JDBC always tests the last row of MySQL table?
How often should Connection, Statement and ResultSet be closed in JDBC?

MySQL INSERT not inserting

Here's my code for making an entry into the MySQL db using PDO.
$sql="INSERT INTO dictionary (entry, meaning) VALUES (:entry,:meaning)";
$prep=$db->prepare($sql);
$prep->bindParam(':entry',$entry);
$prep->bindParam(':meaning',$meaning);
try{
$result=$prep->execute();
}
catch(PDOException $e)
{
echo $e->getMessage();
}
But it's not inserting anything on the db. What could be the problem?
Well, it is useless to ask other people what is wrong with your code. You have to ask your server instead.
So, make sure your PDO throws exceptions on errors. To do so, add this line after connection code
$db->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
Next, move try higher in the code
try{
$sql = "INSERT INTO dictionary (entry, meaning) VALUES (:entry,:meaning)";
$prep = $db->prepare($sql);
$prep->bindParam(':entry',$entry);
$prep->bindParam(':meaning',$meaning);
$result=$prep->execute();
} catch(PDOException $e) {
echo $e->getMessage();
}
and in case of any error you'll be notified of it.

Google plus api not valid access token exception

I'm working with Google+ API and here's what I got. I know that the access token may become invalid in case of the user uninstalling App or de-authorizing it. But I couldn't find how to handle that case. Is it going to throw an exception? If so, what exact exception (maybe someone knows the code)?
I thought that it might be possible to get an http error code like 404 (unauthorized)? If it is, how do I get it?
Here is some code:
try {
$me = $plus->people->get('me')
} catch (Exception $e) {
// Maybe do something with the error code from $e->getCode();
}
Or check the code obtained from I don't know where:
if($code == 401) {
throw new Exception('Expired access token detected. Mailing to admin.', 0);
}
You can get the http status from $e->getCode()

Resources