Pular para o conteúdo
Development

Recuperei uma correção guardada no stash, e uma reprodução ao vivo no meu celular me mostrou um bug diferente

Por Victor Da Luz•
iosswiftdebuggingdev-logdeep-cut-atlas

A aba Playlist no Deep Cut Atlas tinha um bug intermitente: às vezes, ao abrir o app, ela ficava travada em “Loading playlist…” para sempre. Sem erro, sem botão de tentar de novo, nada a fazer além de forçar o fechamento. Uma sessão anterior já tinha diagnosticado e corrigido, testes passando e tudo, e então pausou no meio da verificação e guardou o trabalho no stash. Hoje eu retomei, e virou duas lições separadas.

Recuperando a correção

Aplicar um stash de dois dias atrás contra um código que teve vários commits chegarem desde então é exatamente o tipo de coisa que eu esperava ser doloroso. Não foi. git stash apply fez um merge three-way limpo nos três arquivos afetados, incluindo um arquivo que eu tinha modificado para uma correção não relacionada mais cedo no mesmo dia. Vale lembrar: um stash não é um snapshot congelado contra um commit específico, ele faz merge do mesmo jeito que uma branch.

Um linter que não vê o que você vê

A correção em si adiciona uma proteção de deduplicação de requisições em andamento, para que dois chamadores concorrentes pedindo o conteúdo da mesma playlist compartilhem uma requisição em vez de disputarem duas. O SwiftLint sinalizou na hora: “errors thrown inside this task are not handled.” Só que são tratados. O resultado é capturado, armazenado, e aguardado duas linhas depois com propagação de erro correta. Comparei com duas outras funções no mesmo arquivo fazendo o padrão idêntico que não foram sinalizadas, e a diferença era acadêmica: aquelas usam Task.detached, essa usa um Task { } simples. A regra aparentemente faz pattern-matching na sintaxe do inicializador em vez de rastrear se o resultado é de fato consumido. Eu poderia ter reestruturado o código para escapar dela, mas isso significaria alegar um benefício de concorrência (rodar detached, fora da main actor) que nem se aplica aqui. Um comentário de disable escopado e explicado foi a correção mais honesta.

A reprodução ao vivo que não era o bug que eu estava procurando

Aqui está a parte que realmente importou. Verificação por script não estava disponível para esse caso: meu caminho de automação de UI no dispositivo estava fora do ar (uma dependência do WebDriverAgent deu timeout, sem relação com esse chamado), e execuções com script no dispositivo também não expunham a saída de console do app. Então fiz a passada com o celular na mão eu mesmo.

O que eu vi: travado. Mas não só a Playlist. History não mostrava capa de álbum nenhuma. Discover estava travado no próprio estado de carregamento. Os três, ao mesmo tempo.

Meu primeiro instinto foi um pânico leve: será que a correção não funcionou? Mas o bug que eu tinha corrigido era estreito e específico: uma race entre duas chamadas assíncronas específicas, ambas querendo os dados da mesma playlist. Isso nunca tocou o código do Discover. Algo travado em três abas não relacionadas ao mesmo tempo apontava para um problema diferente e maior, não uma refutação do problema estreito.

Algumas checagens descartaram coisas rápido. O processo do app continuava vivo, não tinha crashado. O wifi estava bem. O app real da Apple Music funcionou perfeitamente no mesmo celular, na mesma rede, no mesmo momento. E nenhuma notificação de hang disparou, o que acabou sendo uma pista útil em si em vez de um beco sem saída: o detector de hang do iOS observa especificamente a main thread, então o silêncio dele sugeria que a UI em si não estava congelada, algo assíncrono só nunca estava terminando.

Eu não tenho um stack trace. Conseguir um precisa do debugger do Xcode conectado ao vivo. Então, em vez de chutar uma causa raiz que eu não consigo ver, separei isso numa investigação própria e entreguei a correção que eu realmente conseguia verificar nos próprios termos dela: testada, revisada, comparada por padrão contra um mecanismo idêntico já rodando em produção em outro lugar do mesmo arquivo. O bug que apareceu no celular é real e precisa de profiling de verdade, não um chute grudado numa correção não relacionada só porque apareceu durante a mesma sessão de teste.

O que vem a seguir

A correção estreita está mesclada. A travada mais ampla (as três abas, sem crash, sem notificação de hang, Apple Music real não afetado) agora é sua própria investigação em aberto, esperando por uma sessão do Instruments ou um debugger conectado ao vivo para de fato ver onde o trabalho assíncrono está travando.

Leitura relacionada

Você também pode achar útil

RackNerd

RackNerd VPS

Hospedagem VPS econômica para serviços leves que funcionam continuamente.

Como afiliado da RackNerd, ganho com compras qualificadas.

Saiba mais
NordPass

NordPass

Gerenciador de senhas da equipe por trás da NordVPN, com um plano gratuito.

Como afiliado da NordPass, ganho com compras qualificadas.

Saiba mais
Airalo

eSIM Airalo

eSIM de dados local para viagens - sem necessidade de trocar um SIM físico.

Este é meu link de indicação da Airalo. Você recebe um desconto no seu primeiro eSIM e eu ganho crédito da Airalo para o meu.

Saiba mais