Skip to content

Commit

Permalink
fix(markdown): the entire response is 500 state when external resourc…
Browse files Browse the repository at this point in the history
…e resolve failed (#286)
  • Loading branch information
Kohei Asai authored Mar 28, 2021
1 parent 130b4c8 commit 277c892
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 56 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { rest } from "msw";
import { setupServer } from "msw/node";
import { scrapeWebpage } from "./scrape";
import { scrapeWebpage } from "./external-resource";

describe("scrapeWebpage()", () => {
const server = setupServer();
Expand Down
14 changes: 14 additions & 0 deletions helpers/scrape.ts → services/external-resource.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,18 @@
import cheerio from "cheerio";
import imageSize from "image-size";

export async function resolveImageDimension(
url: string
): Promise<[number, number] | null> {
const response = await fetch(url);
const { width, height } = imageSize(await (response as any).buffer());

if (width !== undefined && height !== undefined) {
return [width, height];
}

return null;
}

export async function scrapeWebpage(
url: string,
Expand Down
101 changes: 46 additions & 55 deletions services/markdown-processing.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import hash from "hasha";
import { imageSize } from "image-size";
import * as directiveExtension from "mdast-util-directive";
import extractString from "mdast-util-to-string";
import directiveSyntax from "micromark-extension-directive";
Expand All @@ -8,7 +7,7 @@ import remarkStringify from "remark-stringify";
import unified, { CompilerFunction, Processor, Transformer } from "unified";
import type { Node, Parent } from "unist";
import visit from "unist-util-visit";
import { scrapeWebpage } from "../helpers/scrape";
import { resolveImageDimension, scrapeWebpage } from "./external-resource";

export async function parseMarkdown(markdown: string): Promise<Node> {
const processor = unified()
Expand Down Expand Up @@ -61,9 +60,7 @@ function convertHeading() {
}

function convertImageFigure() {
const transformer: Transformer = async (tree) => {
const targetParagraphs: Parameters<visit.Visitor<Parent>>[] = [];

const transformer: Transformer = (tree) => {
visit(tree, "paragraph", (node: Parent, index, parent) => {
if (node.children.length !== 1) {
return;
Expand All @@ -73,32 +70,22 @@ function convertImageFigure() {
return;
}

targetParagraphs.push([node, index, parent]);
parent!.children.splice(index, 1, {
type: "leafDirective",
name: "image-figure",
attributes: {
src: node.children[0]!.url,
caption: node.children[0]!.alt,
},
});
});

await Promise.all(
targetParagraphs.map(async ([node, index, parent]) => {
const imageNode = node.children[0]!;

parent!.children.splice(index, 1, {
type: "leafDirective",
name: "image-figure",
attributes: {
src: imageNode.url,
caption: imageNode.alt,
},
});
})
);
};

return transformer;
}

function convertEmbed() {
const transformer: Transformer = async (tree) => {
const targetParagraphs: Parameters<visit.Visitor<Parent>>[] = [];

const transformer: Transformer = (tree) => {
visit(tree, "paragraph", (node: Parent, index, parent) => {
if (node.children.length !== 1) {
return;
Expand All @@ -108,30 +95,22 @@ function convertEmbed() {
return;
}

targetParagraphs.push([node, index, parent]);
parent!.children.splice(index, 1, {
type: "leafDirective",
name: "embed",
attributes: {
href: node.children[0]!.url,
title: extractString(node.children[0]!),
},
});
});

await Promise.all(
targetParagraphs.map(async ([node, index, parent]) => {
const linkNode = node.children[0]!;

parent!.children.splice(index, 1, {
type: "leafDirective",
name: "embed",
attributes: {
href: linkNode.url,
title: extractString(linkNode),
},
});
})
);
};

return transformer;
}

function resolveEmbedType() {
const transformer: Transformer = async (tree) => {
const transformer: Transformer = (tree) => {
visit(tree, { type: "leafDirective", name: "embed" }, (node) => {
node.name = "webpage-embed";
});
Expand Down Expand Up @@ -168,25 +147,37 @@ function resolveExternalResource() {
return;
}

const response = await fetch(attributes.src as string);
const { width, height } = imageSize(
await (response as any).buffer()
);
try {
const dimension = await resolveImageDimension(attributes.src);

(attributes as any).width = `${width}`;
(attributes as any).height = `${height}`;
if (dimension) {
const [width, height] = dimension;

(attributes as any).width = `${width}`;
(attributes as any).height = `${height}`;
}
} catch (error) {}

break;
case "webpage-embed":
const url = attributes.href as string;
const webpage = await scrapeWebpage(url, {
titleFallback: attributes.title,
});

attributes.href = webpage.href;
attributes.title = webpage.title;
attributes.description = webpage.description;
attributes.imageSrc = webpage.imageSrc;

try {
const webpage = await scrapeWebpage(url, {
titleFallback: attributes.title,
});

attributes.href = webpage.href;
attributes.title = webpage.title;
attributes.description = webpage.description;
attributes.imageSrc = webpage.imageSrc;
} catch (error) {
attributes.href = url;
attributes.title = attributes.title || "Unknown website";
attributes.description =
"Failed to resolve the web page information.";
attributes.imageSrc = "/favicon.png";
}

break;
}
Expand Down

1 comment on commit 277c892

@vercel
Copy link

@vercel vercel bot commented on 277c892 Mar 28, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.