Retorno da API createDocument - "ECMInsertDocumentException"

Bom dia, estou tentando consumir a API:

ambientefluig.com/api/public/ecm/document/createDocument

Porém esporadicamente me deparo com o seguinte erro:

"{"content":"ERROR","message":{"message":"Arquivo Principal não encontrado /outsourcing/totvs/fluig-volume/data/upload/gustavo.maximo/arquivo pdf contendo espaços e acentuação no nome.pdf","detail":"Arquivo Principal não encontrado /outsourcing/totvs/fluig-volume/data/upload/gustavo.maximo/arquivo pdf contendo espaços e acentuação no nome.pdf","type":"ERROR","param":null,"errorCode":"ECMInsertDocumentException"}}"

Isso acontece aleatoriamente quando eu tento subir vários arquivos .pdf em fileira. Já com imagens isso não acontece, mesmo acima de 10mb e nomes com acentuação e espaços.

Ao testar durante horas, percebi um único padrão: ao subir 3 arquivos (qualquer tipo) com o mesmo nome em fileira a API retorna o erro acima.

Então eu desenvolvi um código que renomeia os arquivos antes de efetuar o upload e resolveu.

Entretanto com .pdfs em fileira, com uma chamada atrás da outra, o erro persiste (aleatoriamente, em apenas algumas chamadas, sem padrão aparente relacionado ao nome dos arquivos, talvez o conteúdo do arquivo influencie, não sei).

Código detalhado abaixo:

const uploadMultipleImages = async (files, table) => {
    // Mostra loading
    showLoading();

    // Filtra nomes repetidos no fluig pois a saveDocumentAPI buga ao encontrar 3 nomes de arquivos repetidos
    // Filtro de nomes start

    // Pega todos os nomes que existem sem contar os repetidos
    const namesWithoutDupes = [];
    files.forEach((file) => {
        if (!namesWithoutDupes.includes(file.name)) {
            namesWithoutDupes.push(file.name);
        }
    });

    // Array o qual não contem nomes duplicados, são todos marcados com 1, 2, 3... no final do nome para garantir que não hajam dupes
    const filesWithNameDupePrevention = [];
    namesWithoutDupes.forEach((nonRepeatedName) => {
        let occurences = 0;
        files.filter(e => e.name === nonRepeatedName).forEach((file) => {
            occurences += 1;
            if (occurences > 1) {
                let newFileName = '';
                const lastIndexOfDot = file.name.lastIndexOf('.');
                if (lastIndexOfDot) {
                    newFileName = file.name.substr(0, lastIndexOfDot) + occurences + file.name.substr(lastIndexOfDot);
                } else {
                    newFileName = file.name + occurences;
                }
                filesWithNameDupePrevention.push(new File([file], newFileName, { type: file.type }));
            } else {
                filesWithNameDupePrevention.push(new File([file], file.name, { type: file.type }));
            }
        });
    });

    // Filtro de nomes end

    // Grava arquivo no GED e na tabela
    await Promise.all(filesWithNameDupePrevention.map(async (file) => {
        // Pensei que o problema fosse acentuação e caracteres especiais, logo
        // utilizei encodeURI no nome do arquivo pra não dar pau na API, não deu certo
        // const encodedFile = new File([file], encodeURI(file.name), { type: file.type });

        // Upload no temp do fluig, necessário. (Equivalente a JQuery Fileupload pra quem é oldschool, shout out Caio Rodriguez)
        const data = new FormData();
        data.append('file', file);
        await fetch('/ecm/upload', {
            method: 'POST',
            body: data,
        }).catch(() => {
            toast('Houve um erro ao criar o documento no GED. Contate o suporte da IV2 via suporte@iv2.com.br.', 'danger');
        });

        // Add linhas na tabela
        const row = await addTableLine(table);

        // Salva imagem no GED, retorna id e downloadURL
        const idAndURL = await saveDocumentOnGED(file);

        // Seta downloadURL, id, e nome do arquivo na tabela
        const container = row.querySelector('.fileupload-container');
        setImageDataOnTableRow(container, file.name, idAndURL);
    })).then(() => {
        arrangeTable(table);
        hideLoading();
        saveModalData();
    });
};

No código acima, há 2 seções de importância:

  • Upload no temp do fluig
    • const idAndURL = await saveDocumentOnGED(file);

O primeiro item se refere ao upload na pasta temporária do fluig, faço com fetch ao invés do clássico JQuery Fileupload, funciona igual, não creio que seja o culpado pelo erro mas vale ressaltar.

O segundo item se refere a chamada da API de upload de documentos no GED, código abaixo:

const saveDocumentOnGED = (file => new Promise(async (resolve, reject) => {
    // Salva doc/imagem no GED e salva a id do documento num campo
    // pra poder deletar quando for substituido por outro doc/imagem

    // Pega o id da pasta storage
    const parentId = document.querySelector('#content').dataset.storageFolder;
    // Objeto que incluirá id (GED) do novo doc/imagem e downloadURL
    const returnObj = {};

    // Salva documento no GED e retorna documentId dentro do documentData
    saveDocumentAPI(file, parentId).then((documentData) => {
        // Pega downloadURL através da api de pegar downloadURL
        getDocumentDownloadURL(documentData.content.id).then((downloadURL) => {
            returnObj.downloadURL = downloadURL.content;
            returnObj.documentId = documentData.content.id;
            resolve(returnObj);
        }).catch((error) => {
            toast('Houve um erro ao carregar a imagem. Contate o suporte da IV2 via suporte@iv2.com.br.', 'danger');
            reject(error);
        });
    }).catch((error) => {
        toast('Houve um erro ao salvar a imagem. Contate o suporte da IV2 via suporte@iv2.com.br.', 'danger');
        reject(error);
    });
}));

No código acima, preste atenção no saveDocumentAPI, é nessa hora que o código quebra, ao chamar a API. No retorno (documentData) vem o JSON citado no topo deste post.

Isso acontece as vezes, não consegui ver padrão.

Código da chamada da API (saveDocumentAPI):

const saveDocumentAPI = ((file, parentId) => new Promise((resolve, reject) => {
    const documentPack = {
        description: file.name,
        parentId,
        attachments: [{
            fileName: file.name,
        }],
    };

    fetch(window.location.origin + '/api/public/ecm/document/createDocument', {
        method: 'POST',
        redirect: 'follow',
        headers: new Headers({
            'Content-Type': 'application/json; charset=UTF-8',
        }),
        body: JSON.stringify(documentPack),
    }).then(response => response.json()).then((data) => {
        resolve(data);
    }).catch((error) => {
        reject(error);
    });
}));

Screenshots do código rodando e do erro anexados ao post

Grato pela atenção. Qualquer ajuda é bem vinda.

compartilhar
  1. Você vai ver essas setas em qualquer página de pergunta. Com elas, você pode dizer se uma pergunta ou uma resposta foram relevantes ou não.
  2. Edite sua pergunta ou resposta caso queira alterar ou adicionar detalhes.
  3. Caso haja alguma dúvida sobre a pergunta, adicione um comentário. O espaço de respostas deve ser utilizado apenas para responder a pergunta.
  4. Se o autor da pergunta marcar uma resposta como solucionada, esta marca aparecerá.
  5. Clique aqui para mais detalhes sobre o funcionamento do fluig Forum!

1 resposta

Não é a resposta que estava procurando? Procure outras perguntas com as tags ecm ged api apirest erro fileupload ou faça a sua própria pergunta.