Handle exception in stream processing

This commit is contained in:
René Pfeuffer
2018-08-14 12:58:03 +02:00
parent 01788f3de8
commit fdaff02e01
2 changed files with 30 additions and 11 deletions

View File

@@ -16,7 +16,9 @@ import javax.ws.rs.GET;
import javax.ws.rs.HEAD; import javax.ws.rs.HEAD;
import javax.ws.rs.Path; import javax.ws.rs.Path;
import javax.ws.rs.PathParam; import javax.ws.rs.PathParam;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.core.StreamingOutput; import javax.ws.rs.core.StreamingOutput;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
@@ -41,8 +43,10 @@ public class ContentResource {
StreamingOutput stream = os -> { StreamingOutput stream = os -> {
try { try {
repositoryService.getCatCommand().setRevision(revision).retriveContent(os, path); repositoryService.getCatCommand().setRevision(revision).retriveContent(os, path);
} catch (PathNotFoundException e) {
throw new WebApplicationException(Status.NOT_FOUND);
} catch (RepositoryException e) { } catch (RepositoryException e) {
e.printStackTrace(); throw new WebApplicationException(Status.INTERNAL_SERVER_ERROR);
} }
os.close(); os.close();
}; };
@@ -52,16 +56,16 @@ public class ContentResource {
return responseBuilder.build(); return responseBuilder.build();
} catch (PathNotFoundException e) { } catch (PathNotFoundException e) {
return Response.status(404).build(); return Response.status(Status.NOT_FOUND).build();
} catch (IOException e) { } catch (IOException e) {
LOG.error("error reading repository resource {} from {}/{}", path, namespace, name, e); LOG.error("error reading repository resource {} from {}/{}", path, namespace, name, e);
return Response.status(500).entity(e.getMessage()).build(); return Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
} catch (RepositoryException e) { } catch (RepositoryException e) {
LOG.error("error reading repository resource {} from {}/{}", path, namespace, name, e); LOG.error("error reading repository resource {} from {}/{}", path, namespace, name, e);
return Response.status(500).entity(e.getMessage()).build(); return Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
} }
} catch (RepositoryNotFoundException e) { } catch (RepositoryNotFoundException e) {
return Response.status(404).build(); return Response.status(Status.NOT_FOUND).build();
} }
} }
@@ -76,16 +80,16 @@ public class ContentResource {
appendContentType(path, getHead(revision, path, repositoryService), responseBuilder); appendContentType(path, getHead(revision, path, repositoryService), responseBuilder);
return responseBuilder.build(); return responseBuilder.build();
} catch (PathNotFoundException e) { } catch (PathNotFoundException e) {
return Response.status(404).build(); return Response.status(Status.NOT_FOUND).build();
} catch (IOException e) { } catch (IOException e) {
LOG.error("error reading repository resource {} from {}/{}", path, namespace, name, e); LOG.error("error reading repository resource {} from {}/{}", path, namespace, name, e);
return Response.status(500).entity(e.getMessage()).build(); return Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
} catch (RepositoryException e) { } catch (RepositoryException e) {
LOG.error("error reading repository resource {} from {}/{}", path, namespace, name, e); LOG.error("error reading repository resource {} from {}/{}", path, namespace, name, e);
return Response.status(500).entity(e.getMessage()).build(); return Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
} }
} catch (RepositoryNotFoundException e) { } catch (RepositoryNotFoundException e) {
return Response.status(404).build(); return Response.status(Status.NOT_FOUND).build();
} }
} }

View File

@@ -18,6 +18,7 @@ import sonia.scm.repository.api.RepositoryServiceFactory;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import javax.ws.rs.core.StreamingOutput; import javax.ws.rs.core.StreamingOutput;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.net.URL; import java.net.URL;
@@ -64,8 +65,7 @@ public class ContentResourceTest {
Response response = contentResource.get(NAMESPACE, REPO_NAME, REV, "file"); Response response = contentResource.get(NAMESPACE, REPO_NAME, REV, "file");
assertEquals(200, response.getStatus()); assertEquals(200, response.getStatus());
ByteArrayOutputStream baos = new ByteArrayOutputStream(); ByteArrayOutputStream baos = readOutputStream(response);
((StreamingOutput) response.getEntity()).write(baos);
assertEquals("Hello", baos.toString()); assertEquals("Hello", baos.toString());
} }
@@ -115,6 +115,15 @@ public class ContentResourceTest {
assertEquals("application/octet-stream", response.getHeaderString("Content-Type")); assertEquals("application/octet-stream", response.getHeaderString("Content-Type"));
} }
@Test
public void shouldHandleExceptionsInStreamProcessing() throws Exception {
Response response = contentResource.get(NAMESPACE, REPO_NAME, REV, "MissingFile");
ByteArrayOutputStream baos = readOutputStream(response);
assertEquals(404, response.getStatus());
}
private void mockContentFromResource(String fileName) throws Exception { private void mockContentFromResource(String fileName) throws Exception {
URL url = Resources.getResource(fileName); URL url = Resources.getResource(fileName);
mockContent(fileName, Resources.toByteArray(url)); mockContent(fileName, Resources.toByteArray(url));
@@ -128,4 +137,10 @@ public class ContentResourceTest {
return null; return null;
}).when(catCommand).retriveContent(any(), eq(path)); }).when(catCommand).retriveContent(any(), eq(path));
} }
private ByteArrayOutputStream readOutputStream(Response response) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
((StreamingOutput) response.getEntity()).write(baos);
return baos;
}
} }