Coding Advice

152 views
Skip to first unread message

sben...@bbchs.org

unread,
Aug 7, 2025, 8:29:32 AMAug 7
to Google Apps Script Community
I am not a professional developer at all.  How do you account for when Google Services fail when your code is running.  I use try, catch, finally when I expect errors to happen.  I have a lot of code running my workplace, so I have had Google Services fail in the middle of a long script.  Is there a way to plan for this? When it does it happen it takes a good hour or two to fix it.
Thanks for any input.

George Ghanem

unread,
Aug 7, 2025, 1:05:01 PMAug 7
to google-apps-sc...@googlegroups.com
Usually the things that fail are when you are poking an API or sending an email (and got the wrong email address). So best way to handle these is put those in separate functions and put protection around them with the try/catch setup. If they fail, you can do a reattempt in the hopes it succeeds on second attempt before giving up.

But in general having modular coding and keeping your functions to one page or less makes it easier to debug and find what is failing for a quick fix.

Good luck.

On Thu, Aug 7, 2025, 5:29 a.m. 'sben...@bbchs.org' via Google Apps Script Community <google-apps-sc...@googlegroups.com> wrote:
I am not a professional developer at all.  How do you account for when Google Services fail when your code is running.  I use try, catch, finally when I expect errors to happen.  I have a lot of code running my workplace, so I have had Google Services fail in the middle of a long script.  Is there a way to plan for this? When it does it happen it takes a good hour or two to fix it.
Thanks for any input.

--
You received this message because you are subscribed to the Google Groups "Google Apps Script Community" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-apps-script-c...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/google-apps-script-community/36fc6690-7491-4419-8d91-e0de4fedd434n%40googlegroups.com.

Keith Andersen

unread,
Aug 7, 2025, 6:29:29 PMAug 7
to google-apps-sc...@googlegroups.com
What part takes you an hour to fix.

Can you share a sheet or code?



--

Passions: God, Family, Friends, Scripture, Data Management, Google Sheets + App Script, MS Access, Programing, sharing and much more.

DimuDesigns

unread,
Aug 7, 2025, 8:58:18 PMAug 7
to Google Apps Script Community
First step is to be cognizant of Apps Script's limitations. They are documented under the Quotas For Google Services section of the official Google-supported Apps Script webpage.

Once you are familiar with the typical pitfalls you can plan around them and code defensively.

Note that there will be times where you ultimately hit a wall and GAS just simply falls short. Its applicable to a wide variety of use cases, but some business needs are beyond its capabilities.  

Scott Bennett

unread,
Aug 7, 2025, 9:41:24 PMAug 7
to google-apps-sc...@googlegroups.com
Sorry I did not explain that very well. The code is fine. It’s just I’ve had Google services fail in the middle of running code. It literally says spreadsheet service is not available right now or something to that effect. The fixing it just requires me to go figure out at what step it broke and try to finish all the steps by hand. I am using it to create a lot of things, including PDFs calendar invites, rosters in sheets, etc. so when it breaks in the middle of that, I have to go back and finish it by hand. just kind of wanting some pointers if that ever happens to you guys, we again Google services fail, not the code.
Scott Bennett


Sent from my iPhone 

On Aug 7, 2025, at 5:29 PM, Keith Andersen <contact...@gmail.com> wrote:



SMAARTE Group

unread,
Aug 7, 2025, 9:51:36 PMAug 7
to google-apps-sc...@googlegroups.com
Scott,

I have had some of the same frustrations because there is no 100% uptime for apps script services to execute every single time they're supposed to fire.  I have scripts on a timed trigger that go off perfectly for days in a row and then have one hourly trigger fail because the services just aren't working at that time.  Nothing to do with the code itself.

I have built redundancy into some of my scripts to pick up where things left off, but that takes a lot of extra effort and I don't know of any other way.  I have found asynchronous triggers that scan a specific google sheet to pick up where things left off as a 50%+ workaround when absolutely necessary.  Apps script also has its own temporary memory storage, but I don't think that saved state helps when apps script doesn't want to execute properly.  Then again, chaining less steps together and running multiple scripts with independent triggers and less cross-references also helps reduce complexity (but of course you coded as you did to do complex things more easily).


Regards,
Steve Horvath



Scott Bennett

unread,
Aug 7, 2025, 10:04:35 PMAug 7
to google-apps-sc...@googlegroups.com
Thanks for the input. Again, I am a self-taught programmer and not a professional developer by any stretch of my imagination. Just always looking for ways to improve and use best practices. Thanks again.

Scott Bennett


Sent from my iPhone 

On Aug 7, 2025, at 8:51 PM, SMAARTE Group <in...@smaartegroup.com> wrote:


--
You received this message because you are subscribed to the Google Groups "Google Apps Script Community" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-apps-script-c...@googlegroups.com.

Tim Dobson

unread,
Aug 8, 2025, 6:07:15 AMAug 8
to google-apps-sc...@googlegroups.com
I also have this same problem. I don't have a magic bullet. I have plenty of frustration, and a small amount of ideas.

I guess you could take a leaf from the book of how database updates sometimes work - look up database transaction thingies - and see if there's any concepts you can borrow. I fear there aren't.


> when it breaks in the middle of that, I have to go back and finish it by hand. just kind of wanting some pointers if that ever happens to you guys, we again Google services fail, not the code.

The best answer is to check if has already been done - so you can safely rerun it. "eg does a calendar invite already exist? if no, create, if yes, skip"

It's annoying as anything though - I've seen lots of latency and failures and timeouts on the sheets service and it's like they've moved it to running on a Raspberry Pi.

-Tim

sben...@bbchs.org

unread,
Aug 8, 2025, 8:21:03 AMAug 8
to Google Apps Script Community
Raspberry Pi LOL.  
Thanks for all the input everyone.  I think reading your posts has given me a couple of ideas.  

Kildere S Irineu

unread,
Aug 8, 2025, 9:09:19 AMAug 8
to Google Apps Script Community
Assunto: Re: Como se preparar para falhas nos serviços do Google durante a execução do código?

Olá Scott, Tim, George e todos,

Este é um tópico excelente e uma das dores mais profundas de quem desenvolve com Apps Script. A sua frustração, Scott, é totalmente compreensível. A sensação de que o código está perfeito, mas a plataforma falha no meio de um processo longo, é algo que muitos de nós já sentimos. A piada do Tim sobre o "Raspberry Pi" resume perfeitamente esse sentimento.

Acabei de sair de uma sessão de depuração de dois dias com um desenvolvedor sobre um bug de ambiente raríssimo, então este assunto está muito fresco na minha mente.

As sugestões do George (código modular e try/catch) e do Tim (verificar se a ação já foi feita) são a base da solução. Quero expandir esses conceitos e apresentar uma arquitetura completa que torna seus scripts longos resilientes, reiniciáveis e à prova de falhas.

A estratégia é parar de lutar contra as falhas e os limites de tempo (6 minutos) e, em vez disso, criar um script que espera que elas aconteçam e sabe como se recuperar.

A Arquitetura: O Padrão "Máquina de Estados com Gatilhos"

A ideia é tratar seu script não como uma única execução longa, mas como uma série de execuções curtas e controladas. Cada execução processa um pequeno lote de trabalho, salva seu progresso e agenda a próxima execução.

Componentes Principais:

  1. O Estado (Onde eu parei?): Usamos o PropertiesService para armazenar o estado do nosso script. Ele funciona como um pequeno bloco de notas que persiste entre as execuções. A informação mais comum a ser salva é o índice da última linha da planilha que foi processada com sucesso.

  2. O Lote (Trabalho em Pedaços): Em vez de um loop que processa 1000 linhas, seu script deve ser projetado para processar, por exemplo, apenas 50 linhas por execução.

  3. A Idempotência (Isso já foi feito?): Este é o ponto crucial do Tim. Na sua planilha principal, adicione uma coluna de "Status" (ex: "Pendente", "Em Processo", "Concluído", "Erro"). Antes de executar qualquer ação crítica (criar PDF, enviar convite), seu script DEVE verificar o status naquela linha. Se já for "Concluído", ele simplesmente pula para a próxima. Isso garante que, se você rodar o script novamente, ele não vai criar convites duplicados.

  4. O Gatilho (Me chame de novo): No final de cada execução de lote, o script cria um novo gatilho de tempo para se chamar novamente em, digamos, 1 minuto. Em seguida, ele deleta o gatilho que o iniciou, garantindo que não haja acúmulo de gatilhos.

Exemplo de Fluxo de Código:

JavaScript
// Função principal que será chamada pelo gatilho function processarLotesDeAcoes() { const scriptProperties = PropertiesService.getScriptProperties(); const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Tarefas"); // 1. O ESTADO: Pega a última linha processada ou começa do início (linha 2) let ultimaLinhaProcessada = parseInt(scriptProperties.getProperty('ultimaLinhaProcessada') || '1'); const dados = sheet.getDataRange().getValues(); const TAMANHO_DO_LOTE = 50; // 2. O LOTE: Define o início e o fim do trabalho de hoje const linhaInicial = ultimaLinhaProcessada + 1; const linhaFinal = Math.min(linhaInicial + TAMANHO_DO_LOTE - 1, dados.length - 1); for (let i = linhaInicial; i <= linhaFinal; i++) { const linhaAtual = dados[i]; const status = linhaAtual[10]; // Ex: coluna 11 é a coluna de Status // 3. A IDEMPOTÊNCIA: Verifica se o trabalho já foi feito if (status === 'Concluído') { ultimaLinhaProcessada = i; continue; // Pula para o próximo item } try { // --- SEU CÓDIGO CRÍTICO VAI AQUI --- criarPDF(linhaAtual); enviarConviteCalendario(linhaAtual); // ... outras ações ... // Se tudo deu certo, marca como concluído na planilha sheet.getRange(i + 1, 11).setValue('Concluído'); } catch (e) { // Se um serviço do Google falhar aqui, o status não muda. // Na próxima execução, o script tentará esta mesma linha novamente. Logger.log(`Erro ao processar linha ${i + 1}: ${e.message}`); sheet.getRange(i + 1, 11).setValue('Erro'); } ultimaLinhaProcessada = i; } // 4. O GATILHO: Agenda a próxima execução se ainda houver trabalho a fazer if (ultimaLinhaProcessada < dados.length - 1) { scriptProperties.setProperty('ultimaLinhaProcessada', ultimaLinhaProcessada); criarProximoGatilho(); } else { // Trabalho concluído! Limpa o estado e envia um email de notificação. scriptProperties.deleteAllProperties(); Logger.log("Processo concluído com sucesso!"); } } function criarProximoGatilho() { // Deleta gatilhos antigos para não acumular const gatilhos = ScriptApp.getProjectTriggers(); for (const gatilho of gatilhos) { if (gatilho.getHandlerFunction() === 'processarLotesDeAcoes') { ScriptApp.deleteTrigger(gatilho); } } // Cria um novo gatilho para daqui a 1-2 minutos ScriptApp.newTrigger('processarLotesDeAcoes') .timeBased() .after(2 * 60 * 1000) // 2 minutos .create(); }

Benefícios desta Arquitetura:

  • Resiliência a Falhas: Se o Spreadsheet Service falhar no meio de um lote, o script simplesmente para. O gatilho o iniciará novamente em 2 minutos, e ele tentará processar a mesma linha que falhou, pois o "Status" dela não foi mudado para "Concluído".

  • Contorna o Limite de 6 Minutos: Seu script nunca atingirá o tempo máximo de execução.

  • Recuperação Manual Zero: Você não precisa mais descobrir onde parou. O script sabe exatamente de onde recomeçar.

Implementar este padrão exige um pouco mais de trabalho inicial, mas a paz de espírito que ele proporciona para processos longos e críticos é imensurável.

Espero que esta arquitetura ajude!

Atenciosamente,

Kildere Sobral Irineu 

Michael O'Shaughnessy

unread,
Aug 9, 2025, 9:23:13 PMAug 9
to google-apps-sc...@googlegroups.com
Hello everyone,

It may be worth looking at Bruce McPherson's "Exponential Backoff" approach.  I have not used it BUT it would be something I would look at IF I was experiencing the issues being described.


--
You received this message because you are subscribed to the Google Groups "Google Apps Script Community" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-apps-script-c...@googlegroups.com.

Tim Dobson

unread,
Aug 11, 2025, 5:26:25 PMAug 11
to google-apps-sc...@googlegroups.com
Good advice! Thank you sir!

--
Reply all
Reply to author
Forward
0 new messages