deno: Main thread panic with fetch()

I’m running into some strange issues when fetching image files. Pulled my hair out trying to catch the problematic portion…turns out the problematic portion is simply fetch() itself =), and there is no catching or working around the issue, it simply crashes each time it encounters whatever the problem is. I reduced what I’m doing to a (hopefully) reproducible snippet:

Deno.env.set('RUST_BACKTRACE', 'full'); // needs --allow-env

// content-disposition: inline; filename="2020-04-27_15h06_25.png"; filename*=UTF-8''2020-04-27_15h06_25.png
const working = 'https://community.upc.ch/t5/image/serverpage/image-id/7683i8DD8EAF256FF500C';
// content-disposition: inline; filename="Ursprnge-und-Rezepte-Blog-Banner.png"; filename*=UTF-8''Urspr%C3%BCnge-und-Rezepte-Blog-Banner.png
const panic1 = 'https://community.upc.ch/t5/image/serverpage/image-id/7679iD6978D01CC52670D';
// content-disposition: inline; filename="virtuelle-Untersttzung_blog.jpg"; filename*=UTF-8''virtuelle-Unterst%C3%BCtzung_blog.jpg
const panic2 = 'https://community.upc.ch/t5/image/serverpage/image-id/7611i6132FD57C7312C6D';
// content-disposition: inline; filename="virtuelle-Untersttzung_blog.jpg"; filename*=UTF-8''virtuelle-Unterst%C3%BCtzung_blog.jpg
const panic3 = 'https://community.upc.ch/t5/image/serverpage/image-id/7610i2A587382D4015838';
// content-disposition: inline; filename="Ursprnge-und-Rezepte-Blog-Banner.png"; filename*=UTF-8''Urspr%C3%BCnge-und-Rezepte-Blog-Banner.png
const panic4 = 'https://community.upc.ch/t5/image/serverpage/image-id/7680i0E08F8FBC53FFB86';
// content-disposition: inline; filename="Lg EPG - Update - UPC Community.jpg"; filename*=UTF-8''L%C3%B6sung%20EPG%20-%20Update%20-%20UPC%20Community.jpg
const panic5 = 'https://community.upc.ch/t5/image/serverpage/image-id/6214i47B0827B20634C66';
// content-disposition: inline; filename="Programmbersicht vom 19.1.2019 - TV-Programm von UPC.jpg"; filename*=UTF-8''Programm%C3%BCbersicht%20vom%2019.1.2019%20-%20TV-Programm%20von%20UPC.jpg
const panic6 = 'https://community.upc.ch/t5/image/serverpage/image-id/5030i891681AB69CE5C39';
// content-disposition: inline; filename="Programmbersicht vom 19.1.2019 - TV-Programm von SRF.jpg"; filename*=UTF-8''Programm%C3%BCbersicht%20vom%2019.1.2019%20-%20TV-Programm%20von%20SRF.jpg
const panic7 = 'https://community.upc.ch/t5/image/serverpage/image-id/5030i891681AB69CE5C39';
// content-disposition: inline; filename="Ststes Mobilnetz   UPC.jpg"; filename*=UTF-8''St%C3%A4rkstes%20Mobilnetz%20%20%20UPC.jpg
const panic8 = 'https://community.upc.ch/t5/image/serverpage/image-id/4954i1B3CE88242518135';
// content-disposition: inline; filename="l.JPG"; filename*=UTF-8''l%C3%B6ser.JPG
const panic9 = 'https://community.upc.ch/t5/image/serverpage/image-id/3571i5F26CFABF7C4A92D';
// content-disposition: inline; filename="leere Beitr.JPG"; filename*=UTF-8''leere%20Beitr%C3%A4ge.JPG
const panic10 = 'https://community.upc.ch/t5/image/serverpage/image-id/3449i22A920E6B52DE26C';
// content-disposition: inline; filename="Krmel.JPG"; filename*=UTF-8''Kr%C3%BCmel.JPG
const panic11 = 'https://community.upc.ch/t5/image/serverpage/image-id/3321i50B36E3AE3CA5BEC';
// content-disposition: inline; filename="ein kleiner Lacher fr zwischendurch ;).jpg"; filename*=UTF-8''ein%20kleiner%20Lacher%20f%C3%BCr%20zwischendurch%20%3B%29.jpg
const panic12 = 'https://community.upc.ch/t5/image/serverpage/image-id/3128iB4861C5D5DB8626F';

// let res = await fetch(working);
let res = await fetch(panic1);
// let res = await fetch(panic2, {
//	method: 'HEAD' // doesn't change anything, e.g. definitely a header issue IMHO
//});
res = await res.blob();

console.log(res);

the error I’m getting is:

thread 'main' panicked at 'called Result::unwrap() on an Err value: ToStrError { _priv: () }', cli/ops/fetch.rs:96:42

I thought at first it might be some strange thing with one specific image/file, but then I skipped that one and soon thereafter ran into the same crash again, so it isn’t only one specific file, I think it is more something within the headers of the response that fails not with the actual file-data, because the rust stack trace points to this:

    for (key, val) in res.headers().iter() {
      // no idea why there is .to_string() for key and .to_str() for value =)...is there a difference?
      // forgive the comment, not familiar with the rust side of deno yet
      res_headers.push((key.to_string(), val.to_str().unwrap().to_owned()));
    }

from here https://github.com/denoland/deno/blob/6d964fc607f78b1652a4e04e8a7cf3672fac9d61/cli/ops/fetch.rs#L97

I’m assuming it is specifically this part: val.to_str().unwrap().to_owned() as it calls .unwrap() which is mentioned in the stack trace…

I had a closer look at the headers (via browser inspector > network tab) and the only potentially problematic thing I’m seeing for ALL “panic” files is the content-disposition header that they contain the actual filename the image was uploaded as and when they have (seemingly?) encoded German umlauts in their names, things break. As far as I can take from MDN:

The parameters filename and filename* differ only in that filename* uses the encoding defined in RFC 5987. When both filename and filename* are present in a single header field value, filename* is preferred over filename when both are understood.

so technically that would mean the filename* one is taken, which seems properly encoded? But yeah, just guessing here, the pattern seems quite constant though…

Might be somehow related to those #6649 #6965

PS: Just upgraded to Deno 1.3.1, same issue, but had the same on the version before that, don’t remember what it was, but for sure 1.x!

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 15 (9 by maintainers)

Most upvoted comments

Confirmed @11070 fixes this. The original reproduction does not panic anymore.

#11070 should fix this.