diff --git a/apps/backend/src/api/hex_repo.gleam b/apps/backend/src/api/hex_repo.gleam index 6bab680..2775816 100644 --- a/apps/backend/src/api/hex_repo.gleam +++ b/apps/backend/src/api/hex_repo.gleam @@ -4,6 +4,7 @@ import gleam/http import gleam/http/request import gleam/httpc import gleam/json +import gleam/option import gleam/package_interface import gleam/result import simplifile @@ -35,16 +36,28 @@ fn get_tarball(name: String, version: String) { |> result.map_error(error.FetchError) } +fn read_interface(filepath: String) { + case simplifile.read(filepath) { + Ok(interface) -> Ok(option.Some(interface)) + Error(_) -> Ok(option.None) + } +} + fn read_file(filepath: String) { filepath |> simplifile.read() - |> result.map_error(error.SimplifileError) + |> result.map_error(error.SimplifileError(_, filepath)) } -fn read_package_interface(blob: String) { - blob - |> json.decode(using: package_interface.decoder) - |> result.map_error(error.JsonError) +fn read_package_interface(blob: option.Option(String)) { + case blob { + option.None -> Ok(option.None) + option.Some(blob) -> + blob + |> json.decode(using: package_interface.decoder) + |> result.map_error(error.JsonError) + |> result.map(option.Some) + } } fn read_gleam_toml(blob: String) { @@ -58,7 +71,7 @@ fn extract_package_infos(name: String, version: String) { let req = get_tarball(name, version) use res <- result.try(req) let #(interface, toml) = extract_tar(res.body, name, slug) - use interface_blob <- result.try(read_file(interface)) + use interface_blob <- result.try(read_interface(interface)) use toml_blob <- result.try(read_file(toml)) use interface <- result.try(read_package_interface(interface_blob)) use toml <- result.map(read_gleam_toml(toml_blob)) diff --git a/apps/backend/src/api/signatures.gleam b/apps/backend/src/api/signatures.gleam index 1558b41..00da2c1 100644 --- a/apps/backend/src/api/signatures.gleam +++ b/apps/backend/src/api/signatures.gleam @@ -49,7 +49,9 @@ fn get_package_release_ids(db: pgo.Connection, package: Package) { }) response.rows |> list.first() - |> result.replace_error(error.UnknownError("No release")) + |> result.replace_error(error.UnknownError( + "No release found for " <> package.name <> "@" <> package.version, + )) } fn upsert_package_module( @@ -74,7 +76,9 @@ fn upsert_package_module( }) response.rows |> list.first() - |> result.replace_error(error.UnknownError("No module")) + |> result.replace_error(error.UnknownError( + "No module found for " <> module_name, + )) } fn upsert_type_definitions( diff --git a/apps/backend/src/backend/index/error.gleam b/apps/backend/src/backend/index/error.gleam index 3fead84..e860085 100644 --- a/apps/backend/src/backend/index/error.gleam +++ b/apps/backend/src/backend/index/error.gleam @@ -8,7 +8,7 @@ pub type Error { DatabaseError(pgo.QueryError) FetchError(dynamic.Dynamic) JsonError(json.DecodeError) - SimplifileError(simplifile.FileError) + SimplifileError(simplifile.FileError, String) UnknownError(String) TomlError(tom.ParseError) } diff --git a/apps/backend/src/backend/log_error.gleam b/apps/backend/src/backend/log_error.gleam index 3d57ad8..260ac73 100644 --- a/apps/backend/src/backend/log_error.gleam +++ b/apps/backend/src/backend/log_error.gleam @@ -49,8 +49,9 @@ pub fn log_error(error: error.Error) { wisp.log_warning("JSON error") log_decode_error(error) } - error.SimplifileError(error) -> { + error.SimplifileError(error, filepath) -> { wisp.log_warning("Simplifile error") + wisp.log_warning(" filepath: " <> filepath) log_simplifile(error) } error.UnknownError(error) -> { diff --git a/apps/backend/src/gleam/generate/types.gleam b/apps/backend/src/gleam/generate/types.gleam index 6bc3c58..7d3b3f4 100644 --- a/apps/backend/src/gleam/generate/types.gleam +++ b/apps/backend/src/gleam/generate/types.gleam @@ -151,7 +151,9 @@ fn find_package_release( response.rows |> keep_highest_release(requirement) |> option.map(fn(v) { pair.first(v) }) - |> option.to_result(error.UnknownError("Release not found")) + |> option.to_result(error.UnknownError( + "Release " <> package <> " with conditions " <> requirement <> " not found", + )) } fn keep_highest_release(rows: List(#(Int, String)), requirement: String) { @@ -193,7 +195,9 @@ fn find_type_signature( }) response.rows |> list.first() - |> result.replace_error(error.UnknownError("No type defined")) + |> result.replace_error(error.UnknownError( + "No type found for " <> module <> "." <> name, + )) } fn extract_parameters_relation( @@ -219,7 +223,7 @@ fn get_toml_requirement(gleam_toml: GleamToml, package: String) { |> result.try_recover(fn(_) { tom.get_string(gleam_toml, ["dependencies", package]) }) - |> result.replace_error(error.UnknownError("No dep found")) + |> result.replace_error(error.UnknownError("No dep found for " <> package)) } fn is_prelude(package: String, module: String) { diff --git a/apps/backend/src/tasks/hex.gleam b/apps/backend/src/tasks/hex.gleam index bd8c29f..a2ec893 100644 --- a/apps/backend/src/tasks/hex.gleam +++ b/apps/backend/src/tasks/hex.gleam @@ -10,6 +10,7 @@ import birl.{type Time} import birl/duration import gleam/hexpm.{type Package} import gleam/list +import gleam/option import gleam/order import gleam/otp/supervisor import gleam/pgo @@ -130,7 +131,11 @@ fn insert_package_and_releases( retrier.retry(fn() { let infos = hex_repo.get_package_infos(package.name, r.version) use #(package, gleam_toml) <- result.try(infos) - signatures.extract_signatures(state.db, package, gleam_toml) + case package { + option.None -> Ok([]) + option.Some(package) -> + signatures.extract_signatures(state.db, package, gleam_toml) + } }) }) })