ronantakizawa/codereview-bench huggingface dataset:
Repository: denoland/deno
File: cli/tools/fmt.rs (Rust)

Code before:
  file_text: &str,
  fmt_options: &FmtOptionsConfig,
) -> Result<Option<String>, AnyError> {
  let formatted_str = malva::format_text(
    file_text,
    malva::detect_syntax(file_path).unwrap_or(malva::Syntax::Css),
    &get_resolved_malva_config(fmt_options),
  )
  .map_err(AnyError::from)?;

  Ok(if formatted_str == file_text {
    None
  } else {
    Some(formatted_str)
  })
}

fn format_yaml(
  file_text: &str,
  fmt_options: &FmtOptionsConfig,
) -> Result<Option<String>, AnyError> {
  let ignore_file = file_text
    .lines()
    .take_while(|line| line.starts_with('#'))
    .any(|line| {
      line.strip_prefix('#').unwrap().trim() == "deno-fmt-ignore-file"
    });

  if ignore_file {
    return Ok(None);
  }

  let formatted_str =
    pretty_yaml::format_text(file_text, &get_resolved_yaml_config(fmt_options))
      .map_err(AnyError::from)?;

  Ok(if formatted_str == file_text {
    None
  } else {
    Some(formatted_str)
  })
}

pub fn format_html(
  file_path: &Path,
  file_text: &str,
  fmt_options: &FmtOptionsConfig,
) -> Result<Option<String>, AnyError> {
  let format_result = markup_fmt::format_text(
    file_text,
    markup_fmt::detect_language(file_path)

Review comment (suggestion):
Maybe `starts_with` instead? Someone may add a comment about why they're ignoring

Code after:
  file_text: &str,
  fmt_options: &FmtOptionsConfig,
) -> Result<Option<String>, AnyError> {
  let formatted_str = malva::format_text(
    file_text,
    malva::detect_syntax(file_path).unwrap_or(malva::Syntax::Css),
    &get_resolved_malva_config(fmt_options),
  )
  .map_err(AnyError::from)?;

  Ok(if formatted_str == file_text {
    None
  } else {
    Some(formatted_str)
  })
}

fn format_yaml(
  file_text: &str,
  fmt_options: &FmtOptionsConfig,
) -> Result<Option<String>, AnyError> {
  let ignore_file = file_text
    .lines()
    .take_while(|line| line.starts_with('#'))
    .any(|line| {
      line
        .strip_prefix('#')
        .unwrap()
        .trim()
        .starts_with("deno-fmt-ignore-file")
    });

  if ignore_file {
    return Ok(None);
  }

  let formatted_str =
    pretty_yaml::format_text(file_text, &get_resolved_yaml_config(fmt_options))
      .map_err(AnyError::from)?;

  Ok(if formatted_str == file_text {
    None
  } else {
    Some(formatted_str)
  })
}

pub fn format_html(
  file_path: &Path,
  file_text: &str,
  fmt_options: &FmtOptionsConfig,
Repository: denoland/deno
File: ext/node/polyfills/internal/fs/handle.ts (TypeScript)

Code before:
  writeFile(data, options): Promise<void> {
    return fsCall(promises.writeFile, this, data, options);
  }

  close(): Promise<void> {
    // Note that Deno.close is not async
    return Promise.resolve(core.close(this.fd));
  }

  stat(): Promise<Stats>;
  stat(options: { bigint: false }): Promise<Stats>;
  stat(options: { bigint: true }): Promise<BigIntStats>;
  stat(options?: { bigint: boolean }): Promise<Stats | BigIntStats> {
    return fsCall(promises.fstat, this, options);
  }
}

function fsCall(fn, handle, ...args) {
  if (handle.fd === -1) {
    const err = new Error("file closed");
    throw Object.assign(err, {
      code: "EBADF",
      syscall: fn.name,
    });
  }

  return fn(handle.fd, ...args);
}

export default {
  FileHandle,
};


Review comment (suggestion):
Added a test as well for `fh.writeFile()` to make sure this change is OK.

Code after:
    return fsCall(promises.writeFile, this, data, options);
  }

  close(): Promise<void> {
    // Note that Deno.close is not async
    return Promise.resolve(core.close(this.fd));
  }

  stat(): Promise<Stats>;
  stat(options: { bigint: false }): Promise<Stats>;
  stat(options: { bigint: true }): Promise<BigIntStats>;
  stat(options?: { bigint: boolean }): Promise<Stats | BigIntStats> {
    return fsCall(promises.fstat, this, options);
  }
}

function fsCall(fn, handle, ...args) {
  if (handle.fd === -1) {
    const err = new Error("file closed");
    throw Object.assign(err, {
      code: "EBADF",
      syscall: fn.name,
    });
  }

  return fn(handle.fd, ...args);
}

export default {
  FileHandle,
};
Repository: denoland/deno
File: ext/fetch/dns.rs (Rust)

Code before:
  ) -> Self {
    Self::Hickory(resolver)
  }
}

type SocketAddrs = vec::IntoIter<SocketAddr>;

pub struct ResolveFut {
  inner: JoinHandle<Result<SocketAddrs, io::Error>>,
}

impl Future for ResolveFut {
  type Output = Result<SocketAddrs, io::Error>;

  fn poll(
    mut self: Pin<&mut Self>,
    cx: &mut task::Context<'_>,
  ) -> Poll<Self::Output> {
    Pin::new(&mut self.inner).poll(cx).map(|res| match res {
      Ok(Ok(addrs)) => Ok(addrs),
      Ok(Err(e)) => Err(e),
      Err(join_err) => {
        if join_err.is_cancelled() {
          Err(io::Error::new(io::ErrorKind::Interrupted, join_err))
        } else {
          panic!("gai background task failed: {:?}", join_err)
        }
      }
    })
  }
}

impl Service<Name> for Resolver {
  type Response = SocketAddrs;
  type Error = io::Error;
  type Future = ResolveFut;

  fn poll_ready(
    &mut self,
    _cx: &mut task::Context<'_>,
  ) -> Poll<Result<(), io::Error>> {
    Poll::Ready(Ok(()))
  }

  fn call(&mut self, name: Name) -> Self::Future {
    let task = match self {
      Resolver::Gai(gai_resolver) => {
        let mut resolver = gai_resolver.clone();
        tokio::spawn(async move {
          let result = resolver.call(name).await?;
          let x: Vec<_> = result.into_iter().collect();

Review comment (suggestion):
This should be handled gracefully with an error and not a panic

Code after:
  ) -> Self {
    Self::Hickory(resolver)
  }
}

type SocketAddrs = vec::IntoIter<SocketAddr>;

pub struct ResolveFut {
  inner: JoinHandle<Result<SocketAddrs, io::Error>>,
}

impl Future for ResolveFut {
  type Output = Result<SocketAddrs, io::Error>;

  fn poll(
    mut self: Pin<&mut Self>,
    cx: &mut task::Context<'_>,
  ) -> Poll<Self::Output> {
    Pin::new(&mut self.inner).poll(cx).map(|res| match res {
      Ok(Ok(addrs)) => Ok(addrs),
      Ok(Err(e)) => Err(e),
      Err(join_err) => {
        if join_err.is_cancelled() {
          Err(io::Error::new(io::ErrorKind::Interrupted, join_err))
        } else {
          Err(io::Error::new(io::ErrorKind::Other, join_err))
        }
      }
    })
  }
}

impl Service<Name> for Resolver {
  type Response = SocketAddrs;
  type Error = io::Error;
  type Future = ResolveFut;

  fn poll_ready(
    &mut self,
    _cx: &mut task::Context<'_>,
  ) -> Poll<Result<(), io::Error>> {
    Poll::Ready(Ok(()))
  }

  fn call(&mut self, name: Name) -> Self::Future {
    let task = match self {
      Resolver::Gai(gai_resolver) => {
        let mut resolver = gai_resolver.clone();
        tokio::spawn(async move {
          let result = resolver.call(name).await?;
          let x: Vec<_> = result.into_iter().collect();
Repository: denoland/deno
File: tests/unit_node/process_test.ts (TypeScript)

Code before:
Deno.test(function processVersionsOwnProperty() {
  assert(Object.prototype.hasOwnProperty.call(process, "versions"));
});

Deno.test(function importedExecArgvTest() {
  assert(Array.isArray(importedExecArgv));
});

Deno.test(function importedExecPathTest() {
  assertEquals(importedExecPath, Deno.execPath());
});

Deno.test("process.cpuUsage()", () => {
  const cpuUsage = process.cpuUsage();
  assert(typeof cpuUsage.user === "number");
  assert(typeof cpuUsage.system === "number");
});

Deno.test("process.stdout.columns writable", () => {
  process.stdout.columns = 80;
  assertEquals(process.stdout.columns, 80);
});

Deno.test("getBuiltinModule", () => {
  assert(process.getBuiltinModule("fs"));
  assertEquals(process.getBuiltinModule("something"), undefined);
});


Review comment (suggestion):
Actually please add a test that uses `node:fs` too

Code after:
Deno.test(function processVersionsOwnProperty() {
  assert(Object.prototype.hasOwnProperty.call(process, "versions"));
});

Deno.test(function importedExecArgvTest() {
  assert(Array.isArray(importedExecArgv));
});

Deno.test(function importedExecPathTest() {
  assertEquals(importedExecPath, Deno.execPath());
});

Deno.test("process.cpuUsage()", () => {
  const cpuUsage = process.cpuUsage();
  assert(typeof cpuUsage.user === "number");
  assert(typeof cpuUsage.system === "number");
});

Deno.test("process.stdout.columns writable", () => {
  process.stdout.columns = 80;
  assertEquals(process.stdout.columns, 80);
});

Deno.test("getBuiltinModule", () => {
  assert(process.getBuiltinModule("fs"));
  assert(process.getBuiltinModule("node:fs"));
  assertEquals(process.getBuiltinModule("something"), undefined);
});
Repository: denoland/deno
File: cli/standalone/binary.rs (Rust)

Code before:
            .with_context(|| {
              format!("Failed reading: {}", pending_dir.display())
            })?
            .collect::<Result<Vec<_>, _>>()?;
          entries.sort_by_cached_key(|entry| entry.file_name()); // determinism
          for entry in entries {
            let path = entry.path();
            if !path.is_dir() {
              continue;
            }
            if path.ends_with("node_modules") {
              builder.add_dir_recursive(&path)?;
            } else {
              pending_dirs.push_back(path);
            }
          }
        }
        Ok(builder)
      }
    }
  }
}

fn get_denort_path(deno_exe: PathBuf) -> Option<OsString> {
  let mut denort = deno_exe;
  denort.set_file_name("denort");
  denort.exists().then(|| denort.into_os_string())
}

fn get_dev_binary_path() -> Option<OsString> {
  env::var_os("DENORT_BIN").or_else(|| {
    env::current_exe().ok().and_then(|exec_path| {
      if exec_path
        .components()
        .any(|component| component == Component::Normal("target".as_ref()))
      {
        get_denort_path(exec_path)
      } else {
        None
      }
    })
  })
}

/// This function returns the environment variables specified
/// in the passed environment file.
fn get_file_env_vars(
  filename: String,
) -> Result<IndexMap<String, String>, dotenvy::Error> {
  let mut file_env_vars = IndexMap::new();
  for item in dotenvy::from_filename_iter(filename)? {

Review comment (suggestion):
> Can you test this on Windows? I guess the rt file is called denort there too (without a file extension).

Good point:

```suggestion
  denort.set_file_name(if cfg!(windows) { "denort.exe" } else { "denort" });
```

Code after:
            .unwrap(),
        );
        while let Some(pending_dir) = pending_dirs.pop_front() {
          let mut entries = fs::read_dir(&pending_dir)
            .with_context(|| {
              format!("Failed reading: {}", pending_dir.display())
            })?
            .collect::<Result<Vec<_>, _>>()?;
          entries.sort_by_cached_key(|entry| entry.file_name()); // determinism
          for entry in entries {
            let path = entry.path();
            if !path.is_dir() {
              continue;
            }
            if path.ends_with("node_modules") {
              builder.add_dir_recursive(&path)?;
            } else {
              pending_dirs.push_back(path);
            }
          }
        }
        Ok(builder)
      }
    }
  }
}

fn get_denort_path(deno_exe: PathBuf) -> Option<OsString> {
  let mut denort = deno_exe;
  denort.set_file_name(if cfg!(windows) {
    "denort.exe"
  } else {
    "denort"
  });
  denort.exists().then(|| denort.into_os_string())
}

fn get_dev_binary_path() -> Option<OsString> {
  env::var_os("DENORT_BIN").or_else(|| {
    env::current_exe().ok().and_then(|exec_path| {
      if exec_path
        .components()
        .any(|component| component == Component::Normal("target".as_ref()))
      {
        get_denort_path(exec_path)
      } else {
        None
      }
    })
  })
}
Repository: denoland/deno
File: tests/unit/net_test.ts (TypeScript)

Code before:
      p1 = listener1.accept().then((conn) => {
        conn.close();
        listener1Recv = true;
        p1 = undefined;
        listener1.close();
      }).catch(() => {});
    }
    if (!p2) {
      p2 = listener2.accept().then((conn) => {
        conn.close();
        listener2Recv = true;
        p2 = undefined;
        listener2.close();
      }).catch(() => {});
    }
    const conn = await Deno.connect({ port });
    conn.close();
    await Promise.race([p1, p2]);
  }
});

Deno.test(
  { permissions: { net: true } },
  async function netTcpWithAbortSignal() {
    const controller = new AbortController();
    setTimeout(() => controller.abort(), 1000);
    const error = await assertRejects(
      async () => {
        await Deno.connect({
          hostname: "deno.com",
          port: 50000,
          transport: "tcp",
          signal: controller.signal,
        });
      },
    );
    assert(error instanceof DOMException);
    assertEquals(error.name, "AbortError");
  },
);

Deno.test({
  ignore: Deno.build.os === "linux",
  permissions: { net: true },
}, function netTcpListenReusePortDoesNothing() {
  const listener1 = Deno.listen({ port: 4003, reusePort: true });
  assertThrows(() => {
    Deno.listen({ port: 4003, reusePort: true });
  }, Deno.errors.AddrInUse);
  listener1.close();
});

Review comment (suggestion):
I think 100ms is enough.

```suggestion
    setTimeout(() => controller.abort(), 100);
```

Code after:
      p1 = listener1.accept().then((conn) => {
        conn.close();
        listener1Recv = true;
        p1 = undefined;
        listener1.close();
      }).catch(() => {});
    }
    if (!p2) {
      p2 = listener2.accept().then((conn) => {
        conn.close();
        listener2Recv = true;
        p2 = undefined;
        listener2.close();
      }).catch(() => {});
    }
    const conn = await Deno.connect({ port });
    conn.close();
    await Promise.race([p1, p2]);
  }
});

Deno.test(
  { permissions: { net: true } },
  async function netTcpWithAbortSignal() {
    const controller = new AbortController();
    setTimeout(() => controller.abort(), 100);
    const error = await assertRejects(
      async () => {
        await Deno.connect({
          hostname: "deno.com",
          port: 50000,
          transport: "tcp",
          signal: controller.signal,
        });
      },
    );
    assert(error instanceof DOMException);
    assertEquals(error.name, "AbortError");
  },
);

Deno.test({
  ignore: Deno.build.os === "linux",
  permissions: { net: true },
}, function netTcpListenReusePortDoesNothing() {
  const listener1 = Deno.listen({ port: 4003, reusePort: true });
  assertThrows(() => {
    Deno.listen({ port: 4003, reusePort: true });
  }, Deno.errors.AddrInUse);
  listener1.close();
});
Repository: denoland/deno
File: cli/tools/registry/pm/outdated.rs (Rust)

Code before:
  let workspace = cli_options.workspace();
  let http_client = factory.http_client_provider();
  let deps_http_cache = factory.global_http_cache()?;
  let mut file_fetcher = FileFetcher::new(
    deps_http_cache.clone(),
    CacheSetting::RespectHeaders,
    true,
    http_client.clone(),
    Default::default(),
    None,
  );
  file_fetcher.set_download_log_level(log::Level::Trace);
  let file_fetcher = Arc::new(file_fetcher);
  let npm_fetch_resolver = Arc::new(NpmFetchResolver::new(
    file_fetcher.clone(),
    cli_options.npmrc().clone(),
  ));
  let jsr_fetch_resolver =
    Arc::new(JsrFetchResolver::new(file_fetcher.clone()));

  if !cli_options.start_dir.has_deno_json()
    && !cli_options.start_dir.has_pkg_json()
  {
    bail!(
      "No deno.json or package.json in {:?}.",
      cli_options.initial_cwd(),
    );
  }

  let lockfile_exists = match &cli_options.maybe_lockfile() {
    Some(lockfile) => lockfile.filename.exists(),
    None => false,
  };

  if !lockfile_exists {
    bail!(
      "{}",
      color_print::cformat!(
        "No lockfile in {:?}. Run <u>{}</> to generate one.",
        cli_options.initial_cwd(),
        "deno install"
      )
    );
  }

  let args = dep_manager_args(
    &factory,
    cli_options,
    npm_fetch_resolver.clone(),
    jsr_fetch_resolver.clone(),
  )

Review comment (bug):
Nitpick to not rely on debug formatting:

```suggestion
      "No deno.json or package.json in \"{}\".",
      cli_options.initial_cwd().display(),
```

Code after:
    }
  }

  if !outdated.is_empty() {
    outdated.sort();
    print_outdated_table(&outdated);
    print_suggestion(compatible);
  }

  Ok(())
}

pub async fn outdated(
  flags: Arc<Flags>,
  update_flags: OutdatedFlags,
) -> Result<(), AnyError> {
  let factory = CliFactory::from_flags(flags.clone());
  let cli_options = factory.cli_options()?;
  let workspace = cli_options.workspace();
  let http_client = factory.http_client_provider();
  let deps_http_cache = factory.global_http_cache()?;
  let mut file_fetcher = FileFetcher::new(
    deps_http_cache.clone(),
    CacheSetting::RespectHeaders,
    true,
    http_client.clone(),
    Default::default(),
    None,
  );
  file_fetcher.set_download_log_level(log::Level::Trace);
  let file_fetcher = Arc::new(file_fetcher);
  let npm_fetch_resolver = Arc::new(NpmFetchResolver::new(
    file_fetcher.clone(),
    cli_options.npmrc().clone(),
  ));
  let jsr_fetch_resolver =
    Arc::new(JsrFetchResolver::new(file_fetcher.clone()));

  if !cli_options.start_dir.has_deno_json()
    && !cli_options.start_dir.has_pkg_json()
  {
    bail!(
      "No deno.json or package.json in \"{}\".",
      cli_options.initial_cwd().display(),
    );
  }

  let args = dep_manager_args(
    &factory,
    cli_options,
    npm_fetch_resolver.clone(),
Repository: denoland/deno
File: resolvers/deno/cjs.rs (Rust)

Code before:
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.

#[allow(clippy::disallowed_types)]
use crate::sync::MaybeArc;
use dashmap::DashMap;
use deno_media_type::MediaType;
use node_resolver::env::NodeResolverEnv;
use node_resolver::errors::ClosestPkgJsonError;
use node_resolver::InNpmPackageChecker;
use node_resolver::PackageJsonResolver;
use node_resolver::ResolutionMode;
use url::Url;

/// Keeps track of what module specifiers were resolved as CJS.
///
/// Modules that are `.js`, `.ts`, `.jsx`, and `tsx` are only known to
/// be CJS or ESM after they're loaded based on their contents. So these
/// files will be "maybe CJS" until they're loaded.
#[derive(Debug)]
pub struct CjsTracker<TEnv: NodeResolverEnv> {
  is_cjs_resolver: IsCjsResolver<TEnv>,
  known: DashMap<Url, ResolutionMode>,
}

impl<TEnv: NodeResolverEnv> CjsTracker<TEnv> {
  #[allow(clippy::disallowed_types)]
  pub fn new(
    in_npm_pkg_checker: MaybeArc<dyn InNpmPackageChecker>,
    pkg_json_resolver: MaybeArc<PackageJsonResolver<TEnv>>,

Review comment (refactor):
We should refactor this to not require adding disallowed_types. In the other crates, we create types like `InNpmPackageCheckerRc` and then only use the clippy allow on there.

Code after:
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.

use crate::sync::MaybeDashMap;
use deno_media_type::MediaType;
use node_resolver::env::NodeResolverEnv;
use node_resolver::errors::ClosestPkgJsonError;
use node_resolver::InNpmPackageCheckerRc;
use node_resolver::PackageJsonResolverRc;
use node_resolver::ResolutionMode;
use url::Url;

/// Keeps track of what module specifiers were resolved as CJS.
///
/// Modules that are `.js`, `.ts`, `.jsx`, and `tsx` are only known to
/// be CJS or ESM after they're loaded based on their contents. So these
/// files will be "maybe CJS" until they're loaded.
#[derive(Debug)]
pub struct CjsTracker<TEnv: NodeResolverEnv> {
  is_cjs_resolver: IsCjsResolver<TEnv>,
  known: MaybeDashMap<Url, ResolutionMode>,
}

impl<TEnv: NodeResolverEnv> CjsTracker<TEnv> {
  pub fn new(
    in_npm_pkg_checker: InNpmPackageCheckerRc,
    pkg_json_resolver: PackageJsonResolverRc<TEnv>,
    mode: IsCjsResolutionMode,
  ) -> Self {
    Self {
Repository: denoland/deno
File: resolvers/deno/sync.rs (Rust)

Code before:
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.

pub use inner::*;

#[cfg(feature = "sync")]
mod inner {
  #![allow(clippy::disallowed_types)]

  pub use std::sync::Arc as MaybeArc;

  pub use dashmap::DashMap as MaybeDashMap;
}

#[cfg(not(feature = "sync"))]
mod inner {
  pub use std::rc::Rc as MaybeArc;

  pub use std::collections::HashMap as MaybeDashMap;
}


Review comment (suggestion):
This is the right idea, but I think this will be a compile error because `HashMap` requires `&mut`? We might need to make a struct here with the same interface as DashMap.

Code after:
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.

pub use inner::*;

#[cfg(feature = "sync")]
mod inner {
  #![allow(clippy::disallowed_types)]

  pub use std::sync::Arc as MaybeArc;

  pub use dashmap::DashMap as MaybeDashMap;
}

#[cfg(not(feature = "sync"))]
mod inner {
  use std::hash::RandomState;
  pub use std::rc::Rc as MaybeArc;

  // Wrapper struct that exposes a subset of `DashMap` API.
  #[derive(Default)]
  struct MaybeDashMap<K, V, S = RandomState>(RefCell<HashMap<K, V, S>>);

  impl MaybeDashMap<K, V, S> {
    pub fn get(&'a self, key: &K) -> Option<&'a V> {
      let inner = self.0.borrow();
      inner.get(key)
    }

    pub fn insert(&self, key: K, value: V) -> Option<V> {
      let inner = self.0.borrow_mut();
      inner.insert(key, value)
    }
  }
}
Repository: denoland/deno
File: ext/fs/ops.rs (Rust)

Code before:

/// Maintains a static reference to the string if possible.
pub struct V8MaybeStaticStr(pub Cow<'static, str>);

impl<'s> ToV8<'s> for V8MaybeStaticStr {
  type Error = FastStringV8AllocationError;

  #[inline]
  fn to_v8(
    self,
    scope: &mut v8::HandleScope<'s>,
  ) -> Result<v8::Local<'s, v8::Value>, Self::Error> {
    // todo(https://github.com/denoland/deno_core/pull/986): remove this check
    // when upgrading deno_core
    const MAX_V8_STRING_LENGTH: usize = 536870888;
    if self.0.len() > MAX_V8_STRING_LENGTH {
      return Err(FastStringV8AllocationError);
    }

    Ok(
      match self.0 {
        Cow::Borrowed(text) => FastString::from_static(text),
        Cow::Owned(value) => value.into(),
      }
      .v8_string(scope)
      .unwrap()
      .into(),
    )
  }
}

#[op2(stack_trace)]
#[to_v8]
pub fn op_fs_read_file_text_sync<P>(
  state: &mut OpState,
  #[string] path: String,
) -> Result<V8MaybeStaticStr, FsOpsError>
where
  P: FsPermissions + 'static,
{
  let path = PathBuf::from(path);

  let fs = state.borrow::<FileSystemRc>().clone();
  let mut access_check =
    sync_permission_check::<P>(state.borrow_mut(), "Deno.readFileSync()");
  let str = fs
    .read_text_file_lossy_sync(&path, Some(&mut access_check))
    .map_err(|error| map_permission_error("readfile", error, &path))?;
  Ok(V8MaybeStaticStr(str))
}


Review comment (bug):
You probably want to return error here instead of crashing

Code after:

/// Maintains a static reference to the string if possible.
pub struct V8MaybeStaticStr(pub Cow<'static, str>);

impl<'s> ToV8<'s> for V8MaybeStaticStr {
  type Error = FastStringV8AllocationError;

  #[inline]
  fn to_v8(
    self,
    scope: &mut v8::HandleScope<'s>,
  ) -> Result<v8::Local<'s, v8::Value>, Self::Error> {
    Ok(
      match self.0 {
        Cow::Borrowed(text) => FastString::from_static(text),
        Cow::Owned(value) => value.into(),
      }
      .v8_string(scope)
      .map_err(|_| FastStringV8AllocationError)?
      .into(),
    )
  }
}

#[op2(stack_trace)]
#[to_v8]
pub fn op_fs_read_file_text_sync<P>(
  state: &mut OpState,
  #[string] path: String,
) -> Result<V8MaybeStaticStr, FsOpsError>
where
  P: FsPermissions + 'static,
{
  let path = PathBuf::from(path);

  let fs = state.borrow::<FileSystemRc>().clone();
  let mut access_check =
    sync_permission_check::<P>(state.borrow_mut(), "Deno.readFileSync()");
  let str = fs
    .read_text_file_lossy_sync(&path, Some(&mut access_check))
    .map_err(|error| map_permission_error("readfile", error, &path))?;
  Ok(V8MaybeStaticStr(str))
}

#[op2(async, stack_trace)]
#[to_v8]
pub async fn op_fs_read_file_text_async<P>(
  state: Rc<RefCell<OpState>>,
  #[string] path: String,
  #[smi] cancel_rid: Option<ResourceId>,
) -> Result<V8MaybeStaticStr, FsOpsError>