Google plus api not valid access token exception - google-api

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()

Related

doing something after Laravel's http client exception

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.

How to properly handle Google SDK errors in Google App Script

I am writing a google web app which uses the Admin Directory a lot. However I was wondering how the error handling should be done since I do not get a proper error object back when a request to the api fails.
Example: I want to check if a custom schema exists and if not I want to do something else:
try{
var resp = AdminDirectory.Schemas.get("129898rgv", "someCustomSchema");
}catch(err){
// if schema does not exist do this
schemaNotExistFunction();
Logger.log(err);
}
Unfortunately I do not even get the http status code back from the err. Is there another way to handle errors in Google Apps Script?
Instead of
Logger.log(error)
use
Logger.log('%s, %s',error.message, error.stack);
See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error for a complete list of Error instance properties
The above because Logger.log parses the parameter as string. When you pass an error object error.name is logged, by the other hand by using
Example
Running the following code in an standalone project using the new runtime (V8) will log a couple of messages.
function myFunction() {
try{
SpreadsheetApp.getUi();
} catch (error) {
Logger.log(error);
Logger.log('%s, %s', error.message, error.stack);
}
}
Another alternative is to use console.log instead of Logger.log
function myFunction() {
try{
SpreadsheetApp.getUi();
} catch (error) {
console.log(error);
console.log('%s, %s', error.message, error.stack);
}
}

How to change Web Api Core unauthorized behavior

The default ASP.NET Web Api Core behaviour for unauthorized request is to send 401/403 error with empty content. I'd like to change it by specifying some kind of Json response specifying the error.
But I struggle to find a right place where I can introduce these changes. Official documentation is of no help (read it all). I had a guess that may be I could catch UnathorizedException in my exception filter / middleware but it didn't work out (I guess it gets handled at authorization level or even not thrown at all).
So my question is how can I customize response behavior in case of unauthorized request.
With .Net Core 3 (or may be earlier as well) you can write a middleware to check if the context.Response has a status of 40x and then return a custom object. Below is roughly how I did it:
if (context.Response.StatusCode == (int)HttpStatusCode.Unauthorized)
{
var result = new MyStandardApiResponseDto
{
Error = new MyErrorDto
{
Title = "Unauthorized",
Messages = new List<string> { "You are not authorized to access the resource. Please login again." },
},
Result = null
};
await context.Response.WriteAsync(JsonConvert.SerializeObject(result));
}

JSon seralization error with Web Api

I was getting a self referenceing loop error "Self referencing loop detected for property 'ApplicationInstance' with type 'ASP.global_asax'" returned from a PUT call to a web api.
I added this to the web api config:
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.All;
Now I get a different error:
"The 'ObjectContent`1' type failed to serialize the response body for content type 'application/json; charset=utf-8
InnerException":ExceptionMessage":"Error getting value from 'ReadTimeout' on 'System.Web.HttpInputStream'.","ExceptionType":"Newtonsoft.Json.JsonSerializationException","StackTrace":" at Newtonsoft.Json.Serialization.DynamicValueProvider.GetValue(Object target)...
Per suggestion, I added the ".ReferenceLoopHandling.Ignore;" config. This fixesd the loop error, but not the 'can't read value' error.
I am having some trouble finding a cure for this one.
EDIT - Error is gone. I am hesitant to say yet if it is fixed, because I am not yet sure why the error was there in the first place. I made the error leave by changing my Put code in the web api. It was:
[HttpPut]
public IHttpActionResult Put([FromBody]RecipientDTO recipient)
{
try
{
repo.SaveUpdatedRecipient(recipient);
return Ok(this.GetById(recipient.RecipKey));
}
catch (Exception ex)
{
return BadRequest(ex.ToString());
}
}
and is now:
[HttpPut]
public HttpResponseMessage Put([FromBody]RecipientDTO recipient)
{
try
{
repo.SaveUpdatedRecipient(recipient);
return Request.CreateResponse(HttpStatusCode.OK);
}
catch (Exception ex)
{
ex.ToString();
//ValidationMethods.GetDbValidationExceptions(ex);
return Request.CreateResponse(HttpStatusCode.NotFound);
}
}
I am still working on the error handling portion, but at least the error is gone and the data is saved. I will update when I find out more. Any input is welcome.
To solve the issue add the below line of code to WebApiConfig.cs file in your webapi project
config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;

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).

Resources