ใช้การกู้คืนข้อผิดพลาดและกลยุทธ์การลองใหม่แบบกำหนดเอง
ภาพรวมโดยสังเขป
หัวข้อที่มีชื่อว่า “ภาพรวมโดยสังเขป”บริการเอกสารระดับโปรดักชันต้องทำมากกว่าการดักจับและบันทึกข้อยกเว้น บริการต้องตัดสินใจว่าจะดำเนินการอย่างไรต่อไป เช่นทำงานต่อด้วยผลลัพธ์ที่ลดทอนลง สลับไปใช้เส้นทางการเรนเดอร์สำรอง ลองใหม่ด้วยอินพุตที่เอนจินยอมรับได้ หรือส่งมอบหน้าที่สร้างไว้ก่อนเกิดความล้มเหลว สูตรนี้แสดงกลยุทธ์การกู้คืนสี่แบบที่สร้างบนลำดับชั้นข้อยกเว้นของ NextPDF และเมธอดสำหรับตรวจสอบสถานะเอกสาร:
- การลดทอนอย่างนุ่มนวลเมื่อฟอนต์ล้มเหลว — ดักจับ
NextPDF\Exception\FontNotFoundExceptionสำรองไปยังฟอนต์ที่รับประกันว่าใช้งานได้ แล้วสร้างเอกสารต่อไป - ตัวเรนเดอร์สำรอง — เมื่อเส้นทางภายในกระบวนการ
Document::writeHtml()ปฏิเสธอินพุต ให้ลองใหม่ผ่านDocument::writeHtmlChrome()ซึ่งเป็นบริดจ์ Chrome ของnextpdf/artisan - ลองใหม่ด้วย HTML ทางเลือก — เมื่อเกิด
NextPDF\Exception\HtmlParsingExceptionหรือNextPDF\Exception\CssResolutionBudgetExceededExceptionให้ลองใหม่ด้วย HTML รูปแบบที่ลดความซับซ้อนแล้วและทราบว่าใช้งานได้ - การกู้คืนเอกสารบางส่วน — อ่าน
Document::getNumPages()หลังเกิดความล้มเหลว และบันทึกสิ่งที่สร้างไว้แล้วแทนการทิ้งไป
เมื่อทราบวิธีดักจับในระดับที่เหมาะสมแล้ว หน้าคู่กัน จัดการข้อผิดพลาดด้วยลำดับชั้นข้อยกเว้นของ NextPDF จะอธิบายรายละเอียดของลำดับชั้น ส่วนหน้านี้แสดงสิ่งที่ควรทำ หลัง การดักจับ
สูตรนี้มุ่งไปที่รุ่นคอร์แบบโอเพนซอร์ส (OSS) API ทุกตัวที่ระบุไว้ที่นี่อยู่ใน nextpdf/core ดีเพนเดนซีทางเลือกเพียงตัวเดียวคือ nextpdf/artisan สำหรับการสำรองด้วย Chrome
การติดตั้ง
หัวข้อที่มีชื่อว่า “การติดตั้ง”composer require nextpdf/core:^3กลยุทธ์ตัวเรนเดอร์สำรองยังใช้บริดจ์ Chrome เพิ่มเติม:
composer require nextpdf/artisanเมื่อไม่มี nextpdf/artisan Document::writeHtmlChrome() จะโยน NextPDF\Exception\PageLayoutException แทนที่จะเรนเดอร์ กลยุทธ์การสำรองด้านล่างถือว่าการไม่มีบริดจ์เป็นอีกกรณีหนึ่งที่กู้คืนได้
ภาพรวมเชิงแนวคิด
หัวข้อที่มีชื่อว่า “ภาพรวมเชิงแนวคิด”การกู้คืนอาศัยข้อเท็จจริงสองประการเกี่ยวกับ NextPDF ซึ่งทั้งสองข้อได้รับการตรวจสอบกับซอร์สโค้ดแล้ว
ลำดับชั้นข้อยกเว้นบอกได้ว่าสิ่งใดกู้คืนได้ ข้อยกเว้นเชิงโดเมนทุกตัวสืบทอดจากคลาสฐานแบบนามธรรม NextPDF\Exception\NextPdfException ซึ่งสืบทอดจาก RuntimeException และนำ NextPDF\Contracts\ContextAwareExceptionInterface มาใช้ ดักจับชนิดย่อยที่เฉพาะเจาะจงเพื่อเลือกเส้นทางการกู้คืนให้ตรงกับความล้มเหลวนั้น:
FontNotFoundExceptionมีgetFontName()getSearchPaths()และwasFallbackAttempted()— เพียงพอสำหรับการลองใหม่ด้วยฟอนต์อื่นHtmlParsingExceptionมีgetRule()getPosition()และgetHtmlSnippet()— เพียงพอสำหรับตัดสินใจว่าการลองใหม่แบบเรียบง่ายคุ้มค่าหรือไม่CssResolutionBudgetExceededExceptionมีgetVisits()และgetBudget()— เป็นสัญญาณว่าสไตล์ชีตแบบตัดทอนอาจแก้ปัญหาเซเลกเตอร์ที่ผิดปกติได้- ข้อจำกัดสำคัญประการหนึ่ง:
NextPDF\Support\DegradedExceptionสืบทอดจากRuntimeExceptionโดยตรง ไม่ใช่NextPdfExceptionดังนั้นcatch (NextPdfException $e)จึงไม่ดักจับการปฏิเสธจากนโยบายการลดทอน เมื่อNextPDF\Contracts\DegradationPolicyที่ใช้งานอยู่คือStrictหรือBalancedให้ดักจับDegradedExceptionอย่างชัดเจนเพื่อกู้คืนจากข้อยกเว้นนี้
ตรวจสอบเอกสารได้ระหว่างสร้าง Document เปิดเผยสถานะการสร้างของเอกสารผ่านเมธอดอ่านอย่างเดียว getNumPages() คืนค่าจำนวนหน้าทั้งหมด รวมถึงหน้าที่กำลังทำงานและยังไม่ได้ฟลัช ส่วน getPage() คืนค่าดัชนีฐานศูนย์ของหน้าปัจจุบัน หลังเกิดความล้มเหลวระหว่างการสร้าง ให้อ่าน getNumPages() เพื่อดูว่ามีหน้าที่สมบูรณ์อยู่หรือไม่ จากนั้นเรียก save() หรือ getPdfData() เพื่อส่งออกหน้าเหล่านั้น เอนจินยังบันทึกเหตุการณ์การลดทอนที่ไม่ร้ายแรงด้วย: getWarnings() คืนค่า list<NextPDF\Support\Warning> hasWarnings() รายงานว่ามีการเก็บรวบรวมรายการใดไว้หรือไม่ และ hasDegradedParity() รายงานว่าความเที่ยงตรงของผลลัพธ์ได้รับผลกระทบหรือไม่ เมธอดเหล่านี้ช่วยให้รูทีนการกู้คืนแยกความแตกต่างระหว่าง “สำเร็จโดยไม่มีปัญหา” กับ “สำเร็จแต่ความเที่ยงตรงลดลง” โดยไม่ต้องแยกวิเคราะห์ข้อยกเว้น
นโยบายการลดทอนควบคุมว่าเหตุการณ์ใดควรจัดการเป็นข้อยกเว้น และเหตุการณ์ใดควรจัดการเป็นคำเตือน NextPDF\Core\Config มีค่าเริ่มต้นเป็น DegradationPolicy::Balanced ซึ่งจะเตือนและดำเนินการต่อสำหรับการลดทอนที่มีขอบเขตจำกัด แต่จะโยนข้อยกเว้นเมื่อผลกระทบทำให้ดำเนินต่อไม่ได้ DegradationPolicy::Permissive ไม่โยนข้อยกเว้นเลยและเก็บรวบรวมทุกอย่างไว้ในช่องทางคำเตือน DegradationPolicy::Strict โยนข้อยกเว้นเมื่อมีความเสี่ยงด้านการปฏิบัติตามข้อกำหนด การสูญเสียเชิงความหมาย หรือผลกระทบใดๆ ที่ทำให้ดำเนินต่อไม่ได้ เลือกนโยบายก่อน แล้วจึงเขียนตรรกะการกู้คืนสำหรับรูปแบบความล้มเหลวที่นโยบายนั้นสร้างขึ้น
พื้นผิว API
หัวข้อที่มีชื่อว่า “พื้นผิว API”โค้ดการกู้คืนด้านล่างใช้สมาชิกที่ตรวจสอบแล้วเหล่านี้:
NextPDF\Core\Document::createStandalone(?Config $config = null): self,addPage(),setFont(string $family, string $style = '', float $size = 12.0): static,cell(...),writeHtml(string $html): static,writeHtmlChrome(string $html, ?float $width = null, ?float $height = null): static,save(string $path): void,getPdfData(): string,getNumPages(): int,getPage(): int,getWarnings(): list<Warning>,hasWarnings(): bool,hasDegradedParity(): bool,addFontDirectory(string $directory): static.NextPDF\Core\Config::withDegradationPolicy(DegradationPolicy $policy): selfและdegradationPolicyมีค่าเริ่มต้นเป็นDegradationPolicy::BalancedโดยปริยายNextPDF\Contracts\DegradationPolicy—Strict,Balanced,PermissiveNextPDF\Exception\NextPdfException(ฐานนามธรรม),NextPDF\Exception\FontNotFoundException,NextPDF\Exception\HtmlParsingException,NextPDF\Exception\CssResolutionBudgetExceededException,NextPDF\Exception\WriterException,NextPDF\Exception\PageLayoutExceptionNextPDF\Support\DegradedException(มีcapabilityและpolicy),NextPDF\Support\Capability(id,status,reason,isDegraded()),NextPDF\Support\Warning,NextPDF\Support\WarningSeverity
ตัวอย่างโค้ด — เริ่มต้นอย่างรวดเร็ว
หัวข้อที่มีชื่อว่า “ตัวอย่างโค้ด — เริ่มต้นอย่างรวดเร็ว”รูปแบบการกู้คืนขั้นต่ำที่ยังมีประโยชน์จะดักจับความล้มเหลวจากฟอนต์ที่ขาดหาย สำรองไปยังฟอนต์ที่รับประกันว่าใช้งานได้ แล้วดำเนินการต่อ สนิปเปตนี้ข้ามการจัดการแบบครอบคลุมจากตัวอย่างระดับโปรดักชัน สำหรับตัวจัดการที่สมบูรณ์พร้อมการบันทึกและขอบเขตของ DegradedException โปรดดูตัวอย่างระดับโปรดักชันด้านล่าง
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;use NextPDF\Exception\FontNotFoundException;
$doc = Document::createStandalone();$doc->addPage();
try { // A face that may not be installed on every host. $doc->setFont('CorporateSans', '', 12);} catch (FontNotFoundException $e) { // Recover: fall back to a face the engine always resolves. $doc->setFont('helvetica', '', 12);}
$doc->cell(0, 10, 'Rendered with a recovered font.', newLine: true);$doc->save(getenv('NEXTPDF_COOKBOOK_OUTPUT') ?: __DIR__ . '/out.pdf');ตัวอย่างโค้ด — โปรดักชัน
หัวข้อที่มีชื่อว่า “ตัวอย่างโค้ด — โปรดักชัน”ตัวอย่างฉบับเต็มเชื่อมกลยุทธ์ทั้งสี่แบบเข้าด้วยกันในไปป์ไลน์การเรนเดอร์เดียว ได้แก่ การสำรองฟอนต์ การสำรองตัวเรนเดอร์จากเส้นทางภายในกระบวนการไปยัง Chrome การลองใหม่ด้วย HTML ทางเลือก และการกู้คืนเอกสารบางส่วนที่ขับเคลื่อนโดย getNumPages() ตัวอย่างนี้เคารพช่องทางผลลัพธ์ของฮาร์เนส และไม่ดักจับ Exception แบบเปล่าหรือปล่อยให้บล็อก catch ว่างเปล่า
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Contracts\ContextAwareExceptionInterface;use NextPDF\Contracts\DegradationPolicy;use NextPDF\Core\Config;use NextPDF\Core\Document;use NextPDF\Exception\CssResolutionBudgetExceededException;use NextPDF\Exception\FontNotFoundException;use NextPDF\Exception\HtmlParsingException;use NextPDF\Exception\NextPdfException;use NextPDF\Exception\PageLayoutException;use NextPDF\Exception\WriterException;use NextPDF\Support\DegradedException;
/** * A minimal structured sink. In production this is your PSR-3 logger; the * exception class and its structured context become log fields. * * @param array<string, mixed> $context */function logRecovery(string $message, array $context): void{ fwrite(STDERR, $message . ' ' . json_encode($context, JSON_THROW_ON_ERROR) . "\n");}
/** * Resolve a usable font, degrading from the requested face to a guaranteed * fallback. Returns the face actually applied so the caller can record it. * * @param non-empty-string $requested * @param non-empty-string $fallback * * @return non-empty-string */function applyFontWithFallback(Document $doc, string $requested, string $fallback): string{ try { $doc->setFont($requested, '', 12);
return $requested; } catch (FontNotFoundException $e) { // STRATEGY 1 — graceful degradation on a font failure. logRecovery('Font unavailable; degrading to a guaranteed face', [ 'exception' => $e::class, 'font_name' => $e->getFontName(), 'searched' => $e->getSearchPaths(), 'fallback' => $fallback, ]); $doc->setFont($fallback, '', 12);
return $fallback; }}
/** * Render HTML through the in-process pipeline, then through the Chrome bridge, * then through a simplified HTML variant. Each layer recovers a more specific * failure than the last. */function renderHtmlWithRecovery(Document $doc, string $primaryHtml, string $simplifiedHtml): void{ try { // Primary path: the in-process HTML/CSS pipeline. $doc->writeHtml($primaryHtml);
return; } catch (CssResolutionBudgetExceededException $e) { // STRATEGY 3 — retry with alternative HTML for a pathological selector. logRecovery('CSS resolution budget exceeded; retrying with simplified HTML', [ 'exception' => $e::class, 'visits' => $e->getVisits(), 'budget' => $e->getBudget(), ]); $doc->writeHtml($simplifiedHtml);
return; } catch (HtmlParsingException $e) { // STRATEGY 2 — fall back to the Chrome renderer for input the // in-process parser rejects. The Chrome bridge uses a browser CSS // engine, so it may accept what the in-process parser would not. logRecovery('In-process HTML parse failed; trying the Chrome fallback renderer', [ 'exception' => $e::class, 'rule' => $e->getRule(), 'position' => $e->getPosition(), ]);
try { $doc->writeHtmlChrome($primaryHtml);
return; } catch (PageLayoutException $chromeError) { // The Chrome bridge is absent (nextpdf/artisan not installed) or // rejected the input. Last resort: the simplified HTML variant // through the in-process pipeline. logRecovery('Chrome fallback unavailable; retrying with simplified HTML', [ 'exception' => $chromeError::class, ]); $doc->writeHtml($simplifiedHtml);
return; } }}
// --- Configure the degradation policy up front ---------------------------// Balanced (the default) warns on bounded degradation and throws only on a// blocking impact. A regulated workflow would choose DegradationPolicy::Strict.$config = (new Config())->withDegradationPolicy(DegradationPolicy::Balanced);$doc = Document::createStandalone($config);
$primaryHtml = '<h1>Quarterly report</h1><p>Body paragraph with rich styling.</p>';$simplifiedHtml = '<h1>Quarterly report</h1><p>Body paragraph (simplified).</p>';
$outputPath = getenv('NEXTPDF_COOKBOOK_OUTPUT') ?: __DIR__ . '/out.pdf';
try { $doc->addPage(); $applied = applyFontWithFallback($doc, 'CorporateSans', 'helvetica'); $doc->cell(0, 12, 'Custom error recovery patterns', newLine: true);
renderHtmlWithRecovery($doc, $primaryHtml, $simplifiedHtml);
$doc->save($outputPath);
logRecovery('Document built', [ 'font_applied' => $applied, 'pages' => $doc->getNumPages(), 'has_warnings' => $doc->hasWarnings(), 'degraded_parity' => $doc->hasDegradedParity(), ]);} catch (DegradedException $e) { // BOUNDARY: DegradedException extends RuntimeException directly, NOT // NextPdfException, so the catch-all below would not have caught it. // Under Strict/Balanced policy a blocking degradation lands here. logRecovery('Capability degraded under the active policy; emitting a built partial', [ 'exception' => $e::class, 'capability' => $e->capability->id, 'status' => $e->capability->status->value, 'reason' => $e->capability->reason ?? 'unknown', 'policy' => $e->policy->value, ]); // STRATEGY 4 — partial-document recovery: save whatever pages exist. if ($doc->getNumPages() > 0) { $doc->save($outputPath); }} catch (WriterException $e) { // Serialization or I/O failure: the in-memory document is valid but could // not be written. Surface the stage so infrastructure can act on it. logRecovery('PDF write failed; document was valid in memory', [ 'exception' => $e::class, 'writer_state' => $e->getWriterState(), 'output_path' => $e->getOutputPath(), ]);} catch (NextPdfException $e) { // Catch-all for every other NextPDF\Exception\*. STRATEGY 4 again: if any // complete pages were built before the failure, emit them rather than // discarding the work. $context = ['exception' => $e::class, 'pages' => $doc->getNumPages()]; if ($e instanceof ContextAwareExceptionInterface) { $context += $e->getContext(); } logRecovery('Unrecovered NextPDF failure; attempting a partial save', $context); if ($doc->getNumPages() > 0) { $doc->save($outputPath); }}
fwrite(STDERR, "Recovery pipeline complete.\n");ปล่อย STDOUT ว่างไว้สำหรับฮาร์เนส การวินิจฉัยการกู้คืนจะไปที่ STDERR และไฟล์ Portable Document Format (PDF) จะถูกเขียนไปยัง NEXTPDF_COOKBOOK_OUTPUT เท่านั้น
กรณีขอบและข้อควรระวัง
หัวข้อที่มีชื่อว่า “กรณีขอบและข้อควรระวัง”- จัดเรียงบล็อก catch จากเฉพาะเจาะจงไปยังทั่วไป PHP จับคู่กับ
catchที่เข้ากันได้ตัวแรก การวางcatch (NextPdfException $e)ไว้ก่อนcatch (WriterException $e)จะทำให้บล็อกที่เฉพาะเจาะจงกลายเป็นโค้ดที่ไม่มีทางทำงาน เพราะWriterExceptionสืบทอดจากNextPdfException DegradedExceptionอยู่นอกลำดับชั้น ข้อยกเว้นนี้สืบทอดจากRuntimeExceptionไม่ใช่NextPdfExceptionไปป์ไลน์ที่ดักจับเฉพาะNextPdfExceptionจะปล่อยให้การปฏิเสธจากนโยบายแบบเข้มงวดแพร่กระจายไปโดยไม่ถูกดักจับ ให้ดักจับDegradedException(หรือRuntimeExceptionที่กว้างกว่า) เมื่อมีนโยบายการลดทอนที่ไม่ใช่ค่าเริ่มต้นทำงานอยู่- การสำรองฟอนต์ก็ล้มเหลวได้เช่นกัน หากฟอนต์สำรองของคุณไม่ได้ลงทะเบียนไว้
setFont()ครั้งที่สองจะโยนข้อยกเว้นอีกครั้ง ใช้ชื่อแทนแบบ Base14 เช่นhelveticaซึ่งเอนจินแก้ไขได้โดยไม่ต้องค้นหาในระบบไฟล์ หรือลงทะเบียนฟอนต์ที่มาพร้อมกันผ่านaddFontDirectory()ตอนเริ่มต้นเพื่อให้การสำรองได้รับการรับประกัน getNumPages()นับหน้าที่กำลังทำงานซึ่งยังไม่ได้ฟลัช เมธอดนี้คืนค่าจำนวนหน้าที่ฟลัชแล้วบวกหนึ่งเมื่อมีหน้าเปิดอยู่ในขณะนั้น “การบันทึกบางส่วน” รวมหน้าที่กำลังสร้างเมื่อเกิดความล้มเหลว ซึ่งโดยปกติแล้วเป็นสิ่งที่ต้องการ หากต้องการเฉพาะหน้าที่เสร็จสมบูรณ์เต็มที่ ให้แยกเส้นทางตามgetPage()ด้วย- การสำรองด้วย Chrome เปลี่ยนความเที่ยงตรง ไม่ใช่เพียงความพร้อมใช้งาน ไปป์ไลน์ภายในกระบวนการและบริดจ์ Chrome ใช้เอนจินการจัดวางที่ต่างกัน ดังนั้นเอกสารที่สำรองไปยัง Chrome จึงอาจให้ผลลัพธ์แตกต่างออกไป ถือว่าการสำรองเป็นการกู้คืน ไม่ใช่สิ่งทดแทนแบบโปร่งใส และบันทึกว่าเส้นทางใดสร้างผลลัพธ์
- การลองใหม่ต้องใช้อินพุตที่ทราบว่าใช้งานได้ การลองใหม่ด้วย HTML แบบเรียบง่ายจะช่วยได้ก็ต่อเมื่อรูปแบบที่เรียบง่ายนั้นลดความซับซ้อนลงจริง เช่นมีเซเลกเตอร์ซ้อนกันน้อยลง และไม่มีเชน
:has()ที่ใช้งบประมาณการแก้ไขจนหมด การลองใหม่ด้วยอินพุตเดิมที่ล้มเหลวไปแล้วจะวนกลับไปยังข้อยกเว้นเดิม - ตรวจสอบคำเตือนหลังการรันที่สะอาด การเรนเดอร์ที่คืนค่าโดยไม่โยนข้อยกเว้นก็ยังอาจมีการลดทอนได้ ตรวจสอบ
hasDegradedParity()และอ่านgetWarnings()ก่อนถือว่าผลลัพธ์เที่ยงตรงในระดับพิกเซล ภายใต้DegradationPolicy::Permissiveการลดทอนทุกอย่างเป็นคำเตือน ไม่ใช่ข้อยกเว้น
ประสิทธิภาพ
หัวข้อที่มีชื่อว่า “ประสิทธิภาพ”- การกู้คืนเพิ่มต้นทุนเฉพาะบนเส้นทางความล้มเหลวเท่านั้น NextPDF โยนข้อยกเว้นในสถานะที่ผิดปกติ ดังนั้นการเรนเดอร์ที่ไม่มีปัญหาจึงไม่เสียต้นทุนเพิ่มเติมจาก
try/catchที่ครอบไว้ - การสำรองตัวเรนเดอร์จะรันการเรนเดอร์ซ้ำ ความพยายามภายในกระบวนการจะถูกทิ้งไป และความพยายามด้วย Chrome จะเริ่มต้นใหม่ ดังนั้นในกรณีเลวร้ายที่สุด การเรนเดอร์แบบสำรองจึงมีต้นทุนเท่ากับเวลาการเรนเดอร์ทั้งสองครั้งบวกกับการสื่อสารไปกลับข้ามกระบวนการกับ Chrome เผื่องบประมาณส่วนนี้ไว้เมื่อตั้งค่าการหมดเวลาของคำขอ
- การลองใหม่ด้วย HTML ทางเลือกจะแยกวิเคราะห์เอกสารชุดที่สอง รักษารูปแบบที่เรียบง่ายให้มีขนาดเล็ก เพื่อให้การลองใหม่มีต้นทุนต่ำเมื่อเทียบกับความพยายามหลัก
- การบันทึกบางส่วนจะซีเรียลไลซ์หน้าที่สร้างไว้แล้ว ต้นทุนของการบันทึกบางส่วนขยายตามจำนวนหน้าที่เหลืออยู่ ไม่ใช่ตามงานที่ล้มเหลว
หมายเหตุด้านความปลอดภัย
หัวข้อที่มีชื่อว่า “หมายเหตุด้านความปลอดภัย”- อย่าแสดงข้อความข้อยกเว้นดิบหรือเส้นทางระบบไฟล์แก่ผู้ใช้ปลายทาง ข้อความของ
FontNotFoundExceptionมีไดเรกทอรีที่ค้นหา และWriterExceptionมีเส้นทางผลลัพธ์ ทั้งสองอย่างเปิดเผยโครงสร้างของเซิร์ฟเวอร์ บันทึกบริบทเชิงโครงสร้างไว้ฝั่งเซิร์ฟเวอร์ และคืนค่าข้อความทั่วไปให้ผู้เรียก - ถือว่า HTML ที่ใช้ลองใหม่เป็นอินพุตที่ไม่น่าเชื่อถือในทุกความพยายาม การสำรองและการลองใหม่ด้วย HTML แบบเรียบง่ายยังผ่านขอบเขตอินพุตเดียวกัน ไปป์ไลน์ภายในกระบวนการและบริดจ์ Chrome ต่างใช้นโยบายความปลอดภัยของ HTML ของตนเอง และการลองใหม่ไม่ได้ผ่อนปรนการตรวจสอบความถูกต้องนั้น อย่าสันนิษฐานว่ารูปแบบ “ที่เรียบง่าย” ปลอดภัยกว่าเพียงเพราะคุณเป็นผู้เขียนเอง
- การบันทึกบางส่วนยังคงเป็นการเขียนไฟล์ ใช้กฎการตรวจสอบความถูกต้องของเส้นทาง สิทธิ์ และตำแหน่งจัดเก็บกับผลลัพธ์บางส่วนเช่นเดียวกับผลลัพธ์ที่สมบูรณ์
Document::save()ปฏิเสธสตรีมแร็ปเปอร์และไบต์ว่าง (null byte) และแก้ไขไดเรกทอรีหลักเพื่อปิดกั้นการท่องผ่านเส้นทาง แต่ปลายทางที่คุณส่งเข้ามาเป็นความรับผิดชอบของคุณ
การปฏิบัติตามข้อกำหนด
หัวข้อที่มีชื่อว่า “การปฏิบัติตามข้อกำหนด”สูตรนี้ไม่ได้อ้างมาตรฐานเชิงบรรทัดฐานใดๆ สูตรนี้ประกอบ API ข้อยกเว้นและการตรวจสอบเอกสารสาธารณะของ NextPDF ให้เป็นโฟลว์ควบคุมการกู้คืน ไม่ได้ยืนยันพฤติกรรมที่กำหนดโดย ISO 32000-2 หรือมาตรฐานอื่นใด จึงไม่มีบล็อก citations:
หน้านี้ได้รับการตรวจสอบด้วยโปรไฟล์การทำซ้ำได้แบบ semantic เอกสารที่กู้คืนมี /ID ของเทรลเลอร์และวันที่แก้ไขที่สร้างใหม่ทุกครั้งที่บันทึก ดังนั้นจึงไม่สามารถทำให้เหมือนกันในระดับไบต์ได้ การเปรียบเทียบแบบ abstract syntax tree (AST) เชิงโครงสร้างร่วมกับเมทาดาทาเท่านั้นจึงมีความเสถียรในทุกการรัน
ดูเพิ่มเติม
หัวข้อที่มีชื่อว่า “ดูเพิ่มเติม”- จัดการข้อผิดพลาดด้วยลำดับชั้นข้อยกเว้นของ NextPDF — รายละเอียดการดักจับและบริบทเชิงโครงสร้าง ซึ่งเป็นรากฐานของหน้านี้
- โมดูล Exception — เอกสารอ้างอิงข้อยกเว้นฉบับสมบูรณ์
- โมดูล Support —
DegradedExceptionCapabilityWarningและชนิดการลดทอนต่างๆ - โมดูล Config — การกำหนดค่านโยบายการลดทอน
- เรนเดอร์ PDF อย่างปลอดภัยในเวิร์กเกอร์ที่ทำงานต่อเนื่องยาวนาน — การกู้คืนในเวิร์กเกอร์ที่ใช้รีจิสทรีร่วมกันซ้ำๆ