From 2626c0160e54364f239c6ffdeefa69d254af1789 Mon Sep 17 00:00:00 2001 From: Kenny Daniel Date: Sun, 4 Feb 2024 23:37:18 -0800 Subject: [PATCH] Better URL error handling --- demo.css | 8 ++++++++ demo.js | 57 +++++++++++++++++++++++++++++--------------------------- 2 files changed, 38 insertions(+), 27 deletions(-) diff --git a/demo.css b/demo.css index a1083ba..c4d52c7 100644 --- a/demo.css +++ b/demo.css @@ -52,6 +52,14 @@ input[type="file"] { } #layout { margin-top: 20px; + word-break: break-all; +} +.layout a { + color: #445; + text-decoration: none; +} +.layout a:hover { + text-decoration: underline; } .layout div { background-color: rgba(0, 0, 0, 0.05); diff --git a/demo.js b/demo.js index b00c546..b7c5f7c 100644 --- a/demo.js +++ b/demo.js @@ -28,7 +28,7 @@ dropzone.addEventListener('drop', e => { const item = items[0] if (item.kind === 'string') { item.getAsString(str => { - if (str.startsWith('https')) { + if (str.startsWith('http')) { processUrl(str) } }) @@ -37,30 +37,33 @@ dropzone.addEventListener('drop', e => { }) async function processUrl(url) { - // Check if file is accessible and get its size - const head = await fetch(url, { method: 'HEAD' }) - if (!head.ok) { - dropzone.innerHTML = `${url}` - dropzone.innerHTML += `
Error fetching file\n${head.status} ${head.statusText}
` - return - } - const size = head.headers.get('content-length') - if (!size) { - dropzone.innerHTML = `${url}` - dropzone.innerHTML += '
Error fetching file\nNo content-length header
' - return - } - const asyncBuffer = { - byteLength: Number(size), - slice: async (start, end) => { - const res = await fetch(url, { - headers: { Range: `bytes=${start}-${end - 1}` }, - }) - return res.arrayBuffer() - }, - } try { + // Check if file is accessible and get its size + const head = await fetch(url, { method: 'HEAD' }) + if (!head.ok) { + dropzone.innerHTML = `${url}` + dropzone.innerHTML += `
Error fetching file\n${head.status} ${head.statusText}
` + return + } + const size = head.headers.get('content-length') + if (!size) { + dropzone.innerHTML = `${url}` + dropzone.innerHTML += '
Error fetching file\nNo content-length header
' + return + } + // Construct an AsyncBuffer that fetches file chunks + const asyncBuffer = { + byteLength: Number(size), + slice: async (start, end) => { + const rangeEnd = end === undefined ? '' : end - 1 + const res = await fetch(url, { + headers: { Range: `bytes=${start}-${rangeEnd}` }, + }) + return res.arrayBuffer() + }, + } const metadata = await parquetMetadataAsync(asyncBuffer) + url = `${url}` renderSidebar(asyncBuffer, metadata, url) } catch (e) { console.error('Error fetching file', e) @@ -114,7 +117,7 @@ function fileLayout(metadata, byteLength) { html += cell('PAR1', 0, 4, 4) // magic number for (const rowGroupIndex in metadata.row_groups) { const rowGroup = metadata.row_groups[rowGroupIndex] - html += group(`Row group ${rowGroupIndex} (${rowGroup.total_byte_size} bytes)`) + html += group(`Row group ${rowGroupIndex} (${rowGroup.total_byte_size.toLocaleString()} bytes)`) for (const column of rowGroup.columns) { const columnName = column.meta_data.path_in_schema.join('.') @@ -148,9 +151,9 @@ function cell(name, start, bytes, end) {
` }