void importPlaylistItems(
      List<MusicPlaylistItem> playlistItems,
      IdempotentImportExecutor executor,
      UUID jobId,
      TokensAndUrlAuthData authData)
      throws Exception {
    if (playlistItems != null && !playlistItems.isEmpty()) {
      Map<String, List<MusicPlaylistItem>> playlistItemsByPlaylist =
          playlistItems.stream()
              .filter(playlistItem -> !executor.isKeyCached(playlistItem.toString()))
              .collect(Collectors.groupingBy(MusicPlaylistItem::getPlaylistId));

      for (Entry<String, List<MusicPlaylistItem>> playlistEntry :
          playlistItemsByPlaylist.entrySet()) {
        String originalPlaylistId = playlistEntry.getKey();
        UnmodifiableIterator<List<MusicPlaylistItem>> batches =
            Iterators.partition(playlistEntry.getValue().iterator(), PLAYLIST_ITEM_BATCH_SIZE);
        while (batches.hasNext()) {
          importPlaylistItemBatch(jobId, authData, batches.next(), executor, originalPlaylistId);
        }
      }
    }

    return;
  }
@Test
  public void importPlaylistItemsSkippableFauilre() throws Exception {
    importPlaylistSetUp("p1_id", "p1_title");

    MusicPlaylistItem playlistItem1 =
        new MusicPlaylistItem(
            new MusicRecording(
                "item1_isrc", null, 180000L, new MusicRelease("r1_icpn", null, null), null, false),
            "p1_id",
            1);
    MusicPlaylistItem playlistItem2 =
        new MusicPlaylistItem(
            new MusicRecording(
                "item2_isrc", null, 180000L, new MusicRelease("r1_icpn", null, null), null, false),
            "p1_id",
            1);
    GooglePlaylistItem googlePlaylistItem1 = buildGooglePlaylistItem("item1_isrc", "r1_icpn");
    GooglePlaylistItem googlePlaylistItem2 = buildGooglePlaylistItem("item2_isrc", "r1_icpn");

    BatchPlaylistItemRequest batchPlaylistItemRequest =
        new BatchPlaylistItemRequest(
            Lists.newArrayList(
                new ImportPlaylistItemRequest("p1_id", googlePlaylistItem1),
                new ImportPlaylistItemRequest("p1_id", googlePlaylistItem2)),
            "p1_id");

    BatchPlaylistItemResponse batchPlaylistItemResponse =
        new BatchPlaylistItemResponse(
            new NewPlaylistItemResult[]{
                buildPlaylistItemResult("item1_isrc", "r1_icpn", Code.OK_VALUE, null),
                buildPlaylistItemResult("item2_isrc", "r1_icpn", Code.INVALID_ARGUMENT_VALUE,
                    "Fail to find track matching")
            });

    when(googleMusicHttpApi.importPlaylistItems(eq(batchPlaylistItemRequest)))
        .thenReturn(batchPlaylistItemResponse);

    // Run test
    googleMusicImporter.importPlaylistItems(
        Lists.newArrayList(playlistItem1, playlistItem2), executor, uuid, null);

    // Only log the error not throw.
    assertThat(executor.getErrors()).isEmpty();
  }