[Bug] PDF-export mislukt met "Invalid argument(s): 1" #714
Labels
No labels
accepted
bug
declined
docs
duplicate
enhancement
good first issue
in-progress
needs-info
privacy
security
triage
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
LibreKAT/Ocideck#714
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Gevonden tijdens de beeldkeuring van #606, op een verzonnen pentestrapport-deck.
Wat er gebeurt. Exporteren naar PDF faalt reproduceerbaar met:
Wat het níét is. Het deck bevatte twee videodia's; na het verwijderen daarvan faalde de export nog steeds. Het ligt dus niet aan de video.
Wat wél lukt: de HTML-export op hetzelfde deck.
Waarom dit ertoe doet. PDF is het formaat waarin een pentestrapport de deur uit gaat — voor veel gebruikers de enige export die telt. En de melding wijst nergens heen: "Invalid argument(s): 1" is een Dart-
ArgumentErrordie naar de gebruiker is doorgelekt zonder vertaling naar iets waar hij iets mee kan.Twee dingen om uit te zoeken:
Ongeacht de oorzaak verdient de melding zelf een opknapbeurt: een ruwe
ArgumentErrorhoort niet in een gebruikersdialoog.Reproductie: deck met bevinding-, checklist-, scope-matrix- en bevindingenoverzicht-dia's; Exporteren → Exporteer als PDF.
Opgepakt. Tak:
fix/pdf-export-invalid-argument-714. Eerste vraag is jouw tweede: is de PDF-export altijd stuk of deckafhankelijk? Ik begin met een test per slidetype die een echte PDF laat schrijven — die zegt het meteen, en blijft daarna staan als regressiepoort (in de geest van #615).Twee van je drie punten staan op main:
3dda7ad6(PR #718). Het issue blijft open voor de kern — die heb ik niet kunnen reproduceren, en dat kan ik ook niet zonder jouw deck.Je tweede punt is beantwoord: het is niet altijd. Ik heb een poort gebouwd die élk van de vierentwintig diatypes rendert zoals de app dat doet en er een echte PDF van laat schrijven, plus de vier uit je melding samen in één deck. Allemaal groen. De bestaande exporttests voerden een zelfgemaakte PNG in en konden dus niet zien wat één specifiek diatype aan beeldbytes oplevert; die blinde vlek is nu dicht. De PDF-export is dus niet stuk, en het ligt niet aan een diatype als zodanig.
Wat de poort níét bewaakt heb ik erin gezet: hij draait op 640 px en niet op de 1920 van een echte export, omdat het capturen op exportresolutie onder de testbinding niet klaarkomt. Dat is een echte beperking en geen detail — als het probleem juist aan de resolutie hangt, ziet deze toets het niet.
Je derde punt is af. De melding zegt nu in welke stap de export omviel — voorbereiden, de dia's naar beeld renderen, of het bestand opbouwen en wegschrijven — wat je eraan kunt doen, en pas dáárna de technische regel. Die blijft staan: hij is het enige waarmee een oorzaak te vinden is, en hij hoort in een melding geciteerd te worden. Bij een gestrand render wijst de tekst ook de weg naar de HTML-export.
Dat onderscheid was er niet omdat alle drie de stappen uit dezelfde
trygooien. Dat is precies waaromInvalid argument(s): 1zo nietszeggend was: het zei niet eens wélke helft van de export omviel.Wat ik denk dat er aan de hand is, met de onzekerheid erbij. Waarschijnlijk valt het renderen om, niet het PDF-schrijven. De
tryomsluit ook het rasteren, en rasteren is precies wat PDF en PPTX wél doen en HTML niet — dat verklaart waarom HTML op hetzelfde deck lukte. Maar het is consistent met beide verklaringen, en mijn poort sluit alleen de schrijfkant uit voor de types apart, niet voor jouw inhoud. Ik noem het dus een vermoeden en geen diagnose.Wat ik nodig heb om af te maken:
.md) — zonder reproductie kom ik niet verder dan hierboven.Sneller nog: draai de export één keer opnieuw met de nieuwe melding erin. Die zegt de stap zelf, en dan hoeft niemand meer te raden.
Poort:
make checkgroen (5.888 tests), geverifieerd op de boom die gemerged is.Opgepakt, op een andere invalshoek dan het wachten op het deck. Je noteerde zelf dat de nieuwe poort op 640 px draait en dat een resolutie-afhankelijke fout daar onzichtbaar blijft; dat is toetsbaar zonder het oorspronkelijke deck. Ik bouw de vier dia's uit de melding zelf na en exporteer uit de draaiende app op echte exportresolutie. Reproduceert het niet, dan zeg ik dat en gaat het issue terug op needs-info.
Niet gereproduceerd. Ik heb de zoekruimte flink versmald maar de fout zelf niet te pakken gekregen; hieronder wat er nu uit ligt, en één vraag die volgens mij scherper is dan 'stuur het deck'.
Eén correctie op mijn vorige ronde. De notitie bij de poort zei dat capturen op exportresolutie onder de testbinding niet klaarkomt ('did not complete', gemeten). Dat klopt niet. De lus liep leeg omdat er per ronde maar 1 ms échte tijd voorbijging terwijl het capturen op echte tijd loopt; met een ruimer tijdsbudget haalt 1920 px het ruim — 41 dia's in acht seconden. Vervelend genoeg zette juist die notitie de resolutie buiten beeld als verdachte. Rechtgezet in de poort.
Wat nu uitgesloten is (alles op de vier types uit je melding, en groen):
De vraag: heb je op 'Gecomprimeerd' geëxporteerd? Dat is de enige tak in de PDF-export die nog nergens door een toets werd geraakt, en hij past verdacht goed op je melding: hij bestaat alleen voor PDF (jouw HTML lukte), en hij stuurt de bytes langs een heel ander pad — PNG decoderen, verkleinen, opnieuw als JPEG coderen. Om te laten zien dat die tak echt onbewaakt was: ik heb er 'throw ArgumentError(1)' in gezet — letterlijk jouw melding — en dat viel alleen om op de nieuwe gecomprimeerde toets, op geen enkele andere van de 27.
Dat is nadrukkelijk een hypothese en geen diagnose: ik heb hem groen, niet rood. Maar één ja of nee halveert de zoekruimte opnieuw.
Wat er nu ligt: de poort dekt sinds deze ronde de echte exportbreedte, het compressiepad en gevulde tabellen — 27 toetsen in drie seconden. Als de fout aan een van die drie hing, valt hij voortaan vanzelf om.
Het issue blijft open op needs-info; ik heb het in-progress-label eraf gehaald. Met je antwoord op de compressievraag (of het deck) pak ik hem meteen weer op.
Nog een stukje, en dan de stand van zaken.
Het deck is niet meer te achterhalen, en dat is nu vastgesteld in plaats van aangenomen. Het is tijdens een geautomatiseerde beeldkeuring ín de app gebouwd en nooit als .md weggeschreven — geen Write-aanroep in enige sessie, geen Marp-bestand in de scratchpads, en de sessielogs bevatten alleen gesprekken over deze issue, niet het moment zelf. Er valt dus niets terug te halen.
Wat er wel is gebeurd: de poort dekt sinds
66cbb473(PR #766) de echte exportbreedte (1920), het compressiepad (1280, PNG → decode → resize → JPEG) en gevulde tabellen in plaats van de lege startrijen van Slide.create. 27 toetsen in drie seconden.Nog geprobeerd en niet gelukt: de export aansturen via de échte ExportDialog in een widgettoets, om ook audience, themeProfile, tlp, enforcementPolicy en metadata mee te krijgen — dat is namelijk de laatste laag die mijn toetsen overslaan. Die toets loopt vast, vrijwel zeker op een bevestigingsdialoog (TLP-amber) die mijn opstelling nooit beantwoordt. Ik heb hem weggegooid in plaats van hem half werkend te laten staan; het is een opstellingsprobleem, geen bevinding. Wie hier verder gaat: dáár zit nog een echt gat, en het is de moeite waard om het goed te doen.
Stand: niet gereproduceerd, oorzaak onbekend, issue blijft open op needs-info. Uitgesloten (alles groen): gevulde dia's, 1920 en 1280, compressie, verzegeld deck met TLP en organisatie, 41 dia's. Als je ooit weer op deze melding stuit — één keer exporteren met de huidige versie is genoeg, want die noemt nu zelf welke stap omviel.
Gevonden en gerepareerd. Heropend, want dit is een echte fout en geen onreproduceerbare melding.
De oorzaak. In
_stageText(export_dialog.dart) stond:Dart's
clampweigert een bovengrens onder de ondergrens en gooit danArgumentError(lowerLimit). Zodratotalnul is, is dat dus letterlijkArgumentError(1)— en de tekst daarvan isInvalid argument(s): 1. De melding was de naam van de ondergrens.Wanneer is
totalnul? De rasteraar meldt de precache-stap met het aantal te laden afbeeldingen, en dat is nul bij een deck zonder ook maar één afbeelding.numberwerd berekend vóór de switch, dus ook voor precache — juist de tak dietotal == 0netjes afvangt.Dat verklaart alles wat de melding raar maakte:
ExportService.exportrechtstreeks aan en de rasteraar zónderonStage-callback. Dan wordt_stageTextnooit aangeroepen. De hele fout zat in een laag die geen toets aanraakte.Eén correctie op mijn vorige reactie. Ik schreef dat de dialoogtoets vastliep op een bevestigingsvenster. Dat klopte niet. Hij liep vast op mijn eigen opstelling:
Directory.systemTemp.createTemp()in de body van eentestWidgetskomt nooit terug, want daar draait alles in een FakeAsync-zone. Dat hoort insetUp. De dialoog is prima aanstuurbaar — en zodra dat lukte, viel de fout er meteen uit. Excuses; die verkeerde conclusie heeft de zoektocht een ronde gekost.De reparatie is één regel: bij
total < 1vervalt de bovengrens. De ondergrens 1 blijft — een dia heet '1' en niet '0'.De borging is de toets die ontbrak: de exportknop door de héle dialoog heen, op het deck uit jouw melding, onbewerkt én gecomprimeerd. Die stond eerst rood met exact jouw tekst. Twee valkuilen staan in het commentaar vastgelegd, inclusief die createTemp-val en het feit dat de uitslag in een
SelectableTextstaat en niet in eenText.Ook de foutklasse afgelopen (
grepop.clamp(inlib/): twee andere variabele-grenzen zijn aantoonbaar veilig, één plek inslide_layout_metrics.dartheeft hetzelfde patroon maar geen aantoonbaar bereikbaar pad — apart uitgezet, niet stilzwijgend meegenomen.PR volgt zodra de poort groen is.
Gemerged:
cc59a210(PR #781), op main geverifieerd. De reparatie is één regel — bijtotal < 1vervalt de bovengrens — plus twee lagen borging: de exportknop door de héle dialoog (eerst rood met jouw exacte tekst) en elf goedkope toetsen op de losgetrokken voortgangsregel. Beide vallen om als je de clamp terugzet.Wat er níét in zat: de drie andere manieren waarop een preview omvalt bij een ontaarde breedte (cockpit, tijdlijn, en de voortgangsbalk van checklist/scopematrix). Die kwamen boven bij het aflopen van dezelfde foutklasse en hebben andere oorzaken; ze staan apart en niet stilzwijgend meegenomen.