Repository: microsoftgraph/msgraph-sdk-java
Issue: NoSuchElementException when there is no content in the response in case of an error

<!-- Read me before you submit this issue

First off, thank you for taking the time to open this issue! We do appreciate it. Please bear with us if we don't get to this right away.

If this is a question about the Microsoft Graph service API, or a question about how to use this SDK, please post your question to StackOverflow with the [microsoftgraph] tag.
https://stackoverflow.com/questions/tagged/microsoft-graph

This repo is for the Microsoft Graph Java SDK. Issues opened in this repo should only target this SDK.

Before you open this issue, did you:
- Search the issues to determine whether someone already opened this issue?
- Search StackOverflow for an answer?
- Capture the repro steps and gather the information requested in the steps below to reproduce your scenario?
- Review the samples under github.com/microsoftgraph? They can help for some scenarios.
- Take a look at the functional tests in this repo? They may have an example for you. See the [functional tests](https://github.com/microsoftgraph/msgraph-sdk-java/tree/master/src/test/java/com/microsoft/graph/functional)

Please provide the following before submitting this issue:
- Expected behavior. Please provide **links to the specific [Microsoft Graph documentation](https://developer.microsoft.com/en-us/graph/docs/concepts/overview)** you used to determine the expected behavior. 
- Actual behavior. Provide error codes, stack information, and a [Fiddler](http://www.telerik.com/fiddler) capture of the request and response (please remove personally identifiable information before posting).
- Steps to reproduce the behavior. Include your code, IDE versions, client library versions, and any other information that might be helpful to understand your scenario.
-->

### Expected behavior
The library should not throw an exception even in the case when there is no body in case of an error.



### Actual behavior
The library is throwing an exception when there is no content in the response in case of error. 
```
Caused by: java.util.NoSuchElementException
ERROR|1119-172601634|pool-6-thread-5286	at java.base/java.util.Scanner.throwFor(Scanner.java:937)
ERROR|1119-172601634|pool-6-thread-5286	at java.base/java.util.Scanner.next(Scanner.java:1478)
ERROR|1119-172601634|pool-6-thread-5286	at com.microsoft.graph.http.DefaultHttpProvider.streamToString(DefaultHttpProvider.java:473)
ERROR|1119-172601634|pool-6-thread-5286	at com.microsoft.graph.http.GraphServiceException.createFromConnection(GraphServiceException.java:424)
ERROR|1119-172601634|pool-6-thread-5286	at com.microsoft.graph.http.CoreHttpProvider.handleErrorResponse(CoreHttpProvider.java:487)
ERROR|1119-172601634|pool-6-thread-5286	at com.microsoft.graph.http.CoreHttpProvider.sendRequestInternal(CoreHttpProvider.java:376)
```

### Steps to reproduce the behavior

Steps wise not sure how to reproduce it as we are seeing this error when calling a graph endpoint.

Looks like we are not checking the [iterator](https://github.com/microsoftgraph/msgraph-sdk-java/blob/dev/src/main/java/com/microsoft/graph/http/DefaultHttpProvider.java#L470)  before accessing `next`.

```
 public static String streamToString(final InputStream input) {
        final String httpStreamEncoding = "UTF-8";
        final String endOfFile = "\\\\A";
        final Scanner scanner = new Scanner(input, httpStreamEncoding);
        String scannerString = "";
        try {
        	scanner.useDelimiter(endOfFile);
            scannerString = scanner.next();
        } finally {
        	scanner.close();
        }
        return scannerString;
    }
```
I think we should have 
```
if(scanner.hasNext()){
 scannerString = scanner.next();
}
```

If it is ok, I can raise the MR with the fix.

Thanks



Changed files:
src/test/java/com/microsoft/graph/http/CoreHttpProviderTests.java, src/main/java/com/microsoft/graph/http/GraphServiceException.java, src/test/java/com/microsoft/graph/http/DefaultHttpProviderTests.java, src/main/java/com/microsoft/graph/http/CoreHttpProvider.java, src/main/java/com/microsoft/graph/http/DefaultHttpProvider.java

diff --git a/src/main/java/com/microsoft/graph/http/CoreHttpProvider.java b/src/main/java/com/microsoft/graph/http/CoreHttpProvider.java
index 4489b81410..725327cecf 100644
--- a/src/main/java/com/microsoft/graph/http/CoreHttpProvider.java
+++ b/src/main/java/com/microsoft/graph/http/CoreHttpProvider.java
@@ -555,13 +555,12 @@ public class CoreHttpProvider implements IHttpProvider {
 	public static String streamToString(final InputStream input) {
 		final String httpStreamEncoding = "UTF-8";
 		final String endOfFile = "\\\\A";
-		final Scanner scanner = new Scanner(input, httpStreamEncoding);
 		String scannerString = "";
-		try {
+		try (final Scanner scanner = new Scanner(input, httpStreamEncoding)) {
 			scanner.useDelimiter(endOfFile);
-			scannerString = scanner.next();
-		} finally {
-			scanner.close();
+			if (scanner.hasNext()) {
+				scannerString = scanner.next();
+			}
 		}
 		return scannerString;
 	}
diff --git a/src/main/java/com/microsoft/graph/http/DefaultHttpProvider.java b/src/main/java/com/microsoft/graph/http/DefaultHttpProvider.java
index 093b64771b..08e4f1e5d2 100644
--- a/src/main/java/com/microsoft/graph/http/DefaultHttpProvider.java
+++ b/src/main/java/com/microsoft/graph/http/DefaultHttpProvider.java
@@ -470,13 +470,12 @@ public class DefaultHttpProvider implements IHttpProvider {
     public static String streamToString(final InputStream input) {
         final String httpStreamEncoding = "UTF-8";
         final String endOfFile = "\\\\A";
-        final Scanner scanner = new Scanner(input, httpStreamEncoding);
         String scannerString = "";
-        try {
-        	scanner.useDelimiter(endOfFile);
-            scannerString = scanner.next();
-        } finally {
-        	scanner.close();
+        try (final Scanner scanner = new Scanner(input, httpStreamEncoding)) {
+            scanner.useDelimiter(endOfFile);
+            if (scanner.hasNext()) {
+                scannerString = scanner.next();
+            }
         }
         return scannerString;
     }
diff --git a/src/main/java/com/microsoft/graph/http/GraphServiceException.java b/src/main/java/com/microsoft/graph/http/GraphServiceException.java
index 1ed0124f88..08e24886c1 100644
--- a/src/main/java/com/microsoft/graph/http/GraphServiceException.java
+++ b/src/main/java/com/microsoft/graph/http/GraphServiceException.java
@@ -366,7 +366,7 @@ public class GraphServiceException extends ClientException {
         final String responseMessage = connection.getResponseMessage();
         String rawOutput = "{}";
         if(connection.getInputStream() != null) {
-        	rawOutput = DefaultHttpProvider.streamToString(connection.getInputStream());
+        	rawOutput = CoreHttpProvider.streamToString(connection.getInputStream());
         }
         GraphErrorResponse error;
         try {
diff --git a/src/test/java/com/microsoft/graph/http/CoreHttpProviderTests.java b/src/test/java/com/microsoft/graph/http/CoreHttpProviderTests.java
index dea29b5014..c8c22c8c09 100644
--- a/src/test/java/com/microsoft/graph/http/CoreHttpProviderTests.java
+++ b/src/test/java/com/microsoft/graph/http/CoreHttpProviderTests.java
@@ -5,10 +5,17 @@ import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Map;
 
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
 import org.junit.Ignore;
 import org.junit.Test;
 
@@ -28,6 +35,7 @@ public class CoreHttpProviderTests {
 	
 	private MockAuthenticationProvider mAuthenticationProvider;
     private CoreHttpProvider mProvider;
+    private Gson GSON = new GsonBuilder().create();
 
     @Test
     public void testErrorResponse() throws Exception {
@@ -96,7 +104,27 @@ public class CoreHttpProviderTests {
         HeaderOption h = new HeaderOption("name", "value");
         assertFalse(DefaultHttpProvider.hasHeader(Arrays.asList(h), "blah"));
     }
-    
+
+    @Test
+    public void testStreamToStringReturnsData() {
+        String data = GSON.toJson(Maps.newHashMap(
+                ImmutableMap.<String, String>builder()
+                        .put("key", "value")
+                        .build()));
+        final InputStream inputStream = new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8));
+
+        String convertedData = CoreHttpProvider.streamToString(inputStream);
+        assertEquals(data, convertedData);
+    }
+
+    @Test
+    public void testStreamToStringReturnsEmpty() {
+        final InputStream inputStream = new ByteArrayInputStream(new byte[0]);
+
+        String convertedData = CoreHttpProvider.streamToString(inputStream);
+        assertEquals("", convertedData);
+    }
+
 
     /**
      * Configures the http provider for test cases
diff --git a/src/test/java/com/microsoft/graph/http/DefaultHttpProviderTests.java b/src/test/java/com/microsoft/graph/http/DefaultHttpProviderTests.java
index ae4c671a27..70c5d325d3 100644
--- a/src/test/java/com/microsoft/graph/http/DefaultHttpProviderTests.java
+++ b/src/test/java/com/microsoft/graph/http/DefaultHttpProviderTests.java
@@ -28,13 +28,19 @@ import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
+import java.io.ByteArrayInputStream;
 import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
 
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
 import org.junit.Test;
 
 import com.google.gson.JsonObject;
@@ -58,6 +64,7 @@ public class DefaultHttpProviderTests {
 
     private MockAuthenticationProvider mAuthenticationProvider;
     private DefaultHttpProvider mProvider;
+    private Gson GSON = new GsonBuilder().create();
 
     @Test
     public void testNoContentType() throws Exception {
@@ -369,6 +376,26 @@ public class DefaultHttpProviderTests {
         HeaderOption h = new HeaderOption("name", "value");
         assertFalse(DefaultHttpProvider.hasHeader(Arrays.asList(h), "blah"));
     }
+
+    @Test
+    public void testStreamToStringReturnsData() {
+        String data = GSON.toJson(Maps.newHashMap(
+                ImmutableMap.<String, String>builder()
+                        .put("key", "value")
+                        .build()));
+        final InputStream inputStream = new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8));
+
+        String convertedData = DefaultHttpProvider.streamToString(inputStream);
+        assertEquals(data, convertedData);
+    }
+
+    @Test
+    public void testStreamToStringReturnsEmpty() {
+        final InputStream inputStream = new ByteArrayInputStream(new byte[0]);
+
+        String convertedData = DefaultHttpProvider.streamToString(inputStream);
+        assertEquals("", convertedData);
+    }
     
 
     /**