microsoft / microsoft/simplechat

Update error toast when user tries to drop open file into chat window

Open Beginner friendly
#1,491 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
152
Forks
116
Avg merge
7h 7m
Merged PRs (30d)
122

Description

When a user tries to drop a file that's open in another app into the chat window, a vague error toast pops up in the upper right that doesn't provide enough information.

Image

Trying to upload the same file via the paperclip icon provides much more helpful error:

Image

Suggested fix - make changes similar to the below to application/single_app/static/js/chat/chat-input-actions.js to give the user a clearer message about what went wrong.)

More helpful error message:

Image

New async function

  const fileName = String(file?.name || "selected file").trim() || "selected file";

  try {
    await file.slice(0, Math.min(file.size, 1)).arrayBuffer();
  } catch (error) {
    throw new Error(
      `The browser could not read "${fileName}". Close the file in other apps then try again.`
    );
  }
}

Updated uploadFileToConversation function:

export async function uploadFileToConversation(file) {
  let uploadingIndicatorEl = null;

  try {
    await ensureUploadFileIsReadable(file);
    const groupUploadContext = await resolveGroupUploadContext();
    uploadingIndicatorEl = showFileUploadingMessage();

    // Update the file button to show "Uploading..." state
    const fileBtn = document.getElementById("choose-file-btn");
    if (fileBtn) {
      const fileBtnText = fileBtn.querySelector(".file-btn-text");
      if (fileBtnText) {
        fileBtnText.textContent = "Uploading...";
      }
    }

    const formData = new FormData();
    formData.append("file", file);
    formData.append("conversation_id", currentConversationId);
    if (groupUploadContext) {
      formData.append("group_upload_target_id", groupUploadContext.selectedGroupId);
      groupUploadContext.groupIds.forEach((groupId) => {
        formData.append("upload_scope_group_ids", groupId);
      });
    }

    let response;
    try {
      response = await fetch("/upload", {
        method: "POST",
        body: formData,
      });
    } catch (error) {
      if (error instanceof TypeError) {
        const fileName = String(file?.name || "selected file").trim() || "selected file";
        throw new Error(
          `The browser could not upload "${fileName}". The file may be open in another app, unavailable from cloud storage, or the network connection may have been interrupted. Ensure the file is closed and then try again.`
        );
      }
      throw error;
    }

    hideFileUploadingMessage(uploadingIndicatorEl);
    uploadingIndicatorEl = null;

    const data = await response.json();
    if (!response.ok) {
      console.error("Upload failed:", data.error || "Unknown error");
      throw new Error(data.error || "Upload failed");
    }

    if (data.conversation_id) {
      const uploadedConversationId = data.conversation_id;
      currentConversationId = uploadedConversationId;
      window.currentConversationId = uploadedConversationId;

      // If a title was returned and it's different from "New Conversation",
      // update the conversation title in the UI
      if (data.title && data.title !== "New Conversation") {
        const currentConversationTitleEl = document.getElementById("current-conversation-title");
        if (currentConversationTitleEl) {
          currentConversationTitleEl.textContent = data.title;
        }
      }

      const isCollaborationUpload = Boolean(
        data.is_collaboration_upload
        || window.chatCollaboration?.isCollaborationConversation?.(uploadedConversationId)
      );
      const loadMessagesPromise = isCollaborationUpload && window.chatCollaboration?.activateConversation
        ? window.chatCollaboration.activateConversation(uploadedConversationId)
        : loadMessages(uploadedConversationId);
      if (data.workspace_document_id) {
        registerConversationTaskDocument({
          ...(data.workspace_document || {}),
          id: data.workspace_document_id,
          conversation_id: uploadedConversationId,
          scope: data.workspace_scope,
          status: data.workspace_document?.status || 'Queued for processing',
          percentage_complete: data.workspace_document?.percentage_complete || 0,
          ready: false,
        });
        activateUserWorkspaceContextForChatUpload();
        Promise.resolve(loadMessagesPromise).finally(() => {
          watchChatWorkspaceUploadDocument(data.workspace_document_id, {
            autoSelect: true,
            workspaceScope: data.workspace_scope,
            groupId: data.workspace_document?.group_id || data.group_upload_target?.id || null,
          });
        });
      }
      loadConversations();
    } else {
      console.error("No conversation_id returned from server.");
      showToast("Error: No conversation ID returned from server.", "danger");
    }
    resetFileButton();
  } catch (error) {
    console.error("Error:", error);
    if (!error.isUploadSelectionCancelled) {
      showToast("Error uploading file: " + error.message, "danger");
    }
    resetFileButton();
    if (uploadingIndicatorEl) {
      hideFileUploadingMessage(uploadingIndicatorEl);
    }
  }
}

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Open application/single_app/static/js/chat/chat-input-actions.js and trace the drag-and-drop upload path, especially uploadFileToConversation and its error handling. Compare it with the paperclip upload behavior, then verify that dropping an unreadable or externally locked file shows a specific, actionable toast while normal uploads still complete successfully.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript
Domain
frontend
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
84/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.