Source:
<code>void fillChunks() { try { PutChunk chunkToFill; while (!isChunkFillingDone()) { if (channelReadBuf == null) { channelReadBuf = chunkFillerChannel.getNextByteBuf(0); } if (channelReadBuf != null) { maybeStopTrackingWaitForChannelDataTime(); chunkToFill = getChunkToFill(); if (chunkToFill == null) { maybeStartTrackingWaitForChunkTime(); break; } else { maybeStopTrackingWaitForChunkTime(); bytesFilledSoFar += chunkToFill.fillFrom(channelReadBuf); enforceMaxUploadSize(); if (chunkToFill.isReady() && !chunkToFill.chunkBlobProperties.isEncrypted()) { routerCallback.onPollReady(); } if (!channelReadBuf.isReadable()) { chunkFillerChannel.resolveOldestChunk(null); channelReadBuf = null; } } } else { if (getFreeChunk() != null) { maybeStartTrackingWaitForChannelDataTime(); } break; } } if (chunkFillingCompletedSuccessfully) { PutChunk lastChunk = getBuildingChunk(); if (lastChunk != null) { <START> if (chunkCounter != 0 && (lastChunk.buf == null || lastChunk.buf.readableBytes() == 0)) { <END> logger.trace("The last buffer(s) received from chunkFillerChannel have no data, discarding them."); } else { lastChunk.onFillComplete(true); updateChunkFillerWaitTimeMetrics(); } if (lastChunk.isReady()) { routerCallback.onPollReady(); } } } if (operationCompleted) { PutChunk lastChunk = getBuildingChunk(); if (lastChunk != null) { logger.info("Clear unfinished chunk since operation is completed"); lastChunk.releaseBlobContent(); } } } catch (Exception e) { RouterException routerException = e instanceof RouterException ? (RouterException) e : new RouterException("PutOperation fillChunks encountered unexpected error", e, RouterErrorCode.UnexpectedInternalError); PutChunk lastChunk = getBuildingChunk(); if (lastChunk != null) { lastChunk.releaseBlobContent(); } routerMetrics.chunkFillerUnexpectedErrorCount.inc(); setOperationExceptionAndComplete(routerException); routerCallback.onPollReady(); } }</code><technical_language>is a unit test write reproduce NPE</technical_language>

Target:
void fillChunks() { try { PutChunk chunkToFill; while (!isChunkFillingDone()) { if (channelReadBuf == null) { channelReadBuf = chunkFillerChannel.getNextByteBuf(0); } if (channelReadBuf != null) { maybeStopTrackingWaitForChannelDataTime(); chunkToFill = getChunkToFill(); if (chunkToFill == null) { maybeStartTrackingWaitForChunkTime(); break; } else { maybeStopTrackingWaitForChunkTime(); bytesFilledSoFar += chunkToFill.fillFrom(channelReadBuf); enforceMaxUploadSize(); if (chunkToFill.isReady() && !chunkToFill.chunkBlobProperties.isEncrypted()) { routerCallback.onPollReady(); } if (!channelReadBuf.isReadable()) { chunkFillerChannel.resolveOldestChunk(null); channelReadBuf = null; } } } else { if (getFreeChunk() != null) { maybeStartTrackingWaitForChannelDataTime(); } break; } } if (chunkFillingCompletedSuccessfully) { PutChunk lastChunk = getBuildingChunk(); if (lastChunk != null) { if (chunkCounter != 0 && lastChunk.buf.readableBytes() == 0) { logger.trace("The last buffer(s) received from chunkFillerChannel have no data, discarding them."); lastChunk.releaseBlobContent(); lastChunk.state = ChunkState.Free; } else { lastChunk.onFillComplete(true); updateChunkFillerWaitTimeMetrics(); } if (lastChunk.isReady()) { routerCallback.onPollReady(); } } } if (operationCompleted) { PutChunk lastChunk = getBuildingChunk(); if (lastChunk != null) { logger.info("Clear unfinished chunk since operation is completed"); lastChunk.releaseBlobContent(); } } } catch (Exception e) { RouterException routerException = e instanceof RouterException ? (RouterException) e : new RouterException("PutOperation fillChunks encountered unexpected error", e, RouterErrorCode.UnexpectedInternalError); PutChunk lastChunk = getBuildingChunk(); if (lastChunk != null) { lastChunk.releaseBlobContent(); } routerMetrics.chunkFillerUnexpectedErrorCount.inc(); setOperationExceptionAndComplete(routerException); routerCallback.onPollReady(); } }