Source:
<code>public void onCompletion(String result, Exception exception) { long processingStartTime = System.currentTimeMillis(); try { long routerTime = processingStartTime - operationStartTime; ambryBlobStorageService.frontendMetrics.postTimeInMs.update(routerTime); restRequest.getMetricsTracker().addToTotalCpuTime(routerTime); logger.trace("Callback received for POST"); restResponseChannel.setHeader(RestUtils.Headers.DATE, new GregorianCalendar().getTime()); if (exception == null && result != null) { logger.trace("Successful POST of {}", result); idConverter.convert(restRequest, result, new Callback<String>() { @Override public void onCompletion(String result, Exception exception) { try { <START> setResponseHeaders(result); <END> } catch (RestServiceException e) { if (exception != null) { logger.error("Error while processing IdConverter callback", e); } else { exception = e; } } finally { if (exception != null) { ambryBlobStorageService.frontendMetrics.operationError.inc(); } ambryBlobStorageService.submitResponse(restRequest, restResponseChannel, null, exception); } } }); } else if (exception == null) { exception = new IllegalStateException("Both response and exception are null for PostCallback"); } } catch (Exception e) { ambryBlobStorageService.frontendMetrics.callbackProcessingError.inc(); if (exception != null) { logger.error("Error while processing Router callback", e); } else { exception = e; } } finally { long processingTime = System.currentTimeMillis() - processingStartTime; ambryBlobStorageService.frontendMetrics.postCallbackProcessingTimeInMs.update(processingTime); restRequest.getMetricsTracker().addToTotalCpuTime(processingTime); if (exception != null) { ambryBlobStorageService.frontendMetrics.operationError.inc(); ambryBlobStorageService.submitResponse(restRequest, restResponseChannel, null, exception); } } }</code><technical_language>do set headers irrespective of exception</technical_language>

Target:
public void onCompletion(String result, Exception exception) { long processingStartTime = System.currentTimeMillis(); try { long routerTime = processingStartTime - operationStartTime; ambryBlobStorageService.frontendMetrics.postTimeInMs.update(routerTime); restRequest.getMetricsTracker().addToTotalCpuTime(routerTime); logger.trace("Callback received for POST"); restResponseChannel.setHeader(RestUtils.Headers.DATE, new GregorianCalendar().getTime()); if (exception == null && result != null) { logger.trace("Successful POST of {}", result); idConverter.convert(restRequest, result, new Callback<String>() { @Override public void onCompletion(String result, Exception exception) { if (exception == null) { try { setResponseHeaders(result); } catch (RestServiceException e) { exception = e; } } else { ambryBlobStorageService.frontendMetrics.operationError.inc(); } ambryBlobStorageService.submitResponse(restRequest, restResponseChannel, null, exception); } }); } else if (exception == null) { exception = new IllegalStateException("Both response and exception are null for PostCallback"); } } catch (Exception e) { ambryBlobStorageService.frontendMetrics.callbackProcessingError.inc(); if (exception != null) { logger.error("Error while processing Router callback", e); } else { exception = e; } } finally { long processingTime = System.currentTimeMillis() - processingStartTime; ambryBlobStorageService.frontendMetrics.postCallbackProcessingTimeInMs.update(processingTime); restRequest.getMetricsTracker().addToTotalCpuTime(processingTime); if (exception != null) { ambryBlobStorageService.frontendMetrics.operationError.inc(); ambryBlobStorageService.submitResponse(restRequest, restResponseChannel, null, exception); } } }