Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: error reporting with eyre #240

Merged
merged 8 commits into from
Oct 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

71 changes: 36 additions & 35 deletions crates/cli/src/cache.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::path::{Path, PathBuf};

use color_eyre::{eyre::eyre, Result};
use serde::{Deserialize, Serialize};
use tokio::{
fs::File,
Expand All @@ -8,7 +9,7 @@ use tokio::{
use tracing::debug;
use xxhash_rust::xxh3::Xxh3;

use crate::{config::Config, error::Error};
use crate::config::Config;

const BUFFER_SIZE: usize = 16384; // 16 KB buffer
type Hash = u64;
Expand All @@ -22,7 +23,7 @@ struct DeployedContract {
// Porcelain

impl Config {
pub async fn contract_has_changed(&self, file: &Path) -> Result<bool, Error> {
pub async fn contract_has_changed(&self, file: &Path) -> Result<bool> {
let cur_hash: Hash = Self::gen_hash(file).await?;
debug!("current file hash: {}", cur_hash);

Expand All @@ -39,20 +40,17 @@ impl Config {
}

/// Return a hash of the given file's contents
pub async fn gen_hash(file: &Path) -> Result<Hash, Error> {
let file = File::open(file)
.await
.map_err(|e| Error::GenericErr(e.to_string()))?;
pub async fn gen_hash(file: &Path) -> Result<Hash> {
let file = File::open(file).await?;

let mut reader = BufReader::new(file);

let mut hasher = Xxh3::new();

let mut buffer = [0; BUFFER_SIZE];
loop {
let bytes_read = reader
.read(&mut buffer)
.await
.map_err(|e| Error::GenericErr(e.to_string()))?;
let bytes_read = reader.read(&mut buffer).await?;

if bytes_read == 0 {
break;
}
Expand All @@ -65,7 +63,7 @@ impl Config {
Ok(hash)
}

pub async fn save_codeid_to_cache(&self, file: &Path, code_id: u64) -> Result<(), Error> {
pub async fn save_codeid_to_cache(&self, file: &Path, code_id: u64) -> Result<()> {
let contract_hash = Self::gen_hash(file).await?;
let dest = Self::to_cache_path(self, file)?;
let deployed_contract = DeployedContract {
Expand All @@ -76,7 +74,7 @@ impl Config {
Self::write_to_cache(dest.as_path(), &deployed_contract).await
}

pub async fn get_cached_codeid(&self, file: &Path) -> Result<u64, Error> {
pub async fn get_cached_codeid(&self, file: &Path) -> Result<u64> {
let cache_path = Self::to_cache_path(self, file)?;
let code_id = Self::read_from_cache(cache_path.as_path()).await?.code_id;

Expand All @@ -85,12 +83,16 @@ impl Config {

// Plumbing

fn to_cache_path(&self, file: &Path) -> Result<PathBuf, Error> {
fn to_cache_path(&self, file: &Path) -> Result<PathBuf> {
// Get cache filepath (".quartz/cache/example.wasm.json") from "example.wasm" filepath
let mut filename = file
.file_name()
.ok_or(Error::PathNotFile(file.display().to_string()))?
.ok_or(eyre!(
"file at cache filepath does not exist {}",
file.display()
))?
.to_os_string();

filename.push(".json");

let cached_file_path = Self::cache_dir(self)?.join::<PathBuf>(filename.into());
Expand All @@ -99,52 +101,51 @@ impl Config {
}

/// Retreive hash from cache file
async fn read_from_cache(cache_file: &Path) -> Result<DeployedContract, Error> {
let content = tokio::fs::read_to_string(cache_file)
.await
.map_err(|e| Error::GenericErr(e.to_string()))?;
serde_json::from_str(&content).map_err(|e| Error::GenericErr(e.to_string()))
async fn read_from_cache(cache_file: &Path) -> Result<DeployedContract> {
let content = tokio::fs::read_to_string(cache_file).await?;

serde_json::from_str(&content).map_err(|e| eyre!(e))
}

/// Write a given file's contents hash to a file in cache directory
async fn write_to_cache(cache_file: &Path, data: &DeployedContract) -> Result<(), Error> {
let content = serde_json::to_string(data).map_err(|e| Error::GenericErr(e.to_string()))?;
async fn write_to_cache(cache_file: &Path, data: &DeployedContract) -> Result<()> {
let content = serde_json::to_string(data)?;

tokio::fs::write(cache_file, content)
.await
.map_err(|e| Error::GenericErr(e.to_string()))
.map_err(|e| eyre!(e))
}

pub fn cache_dir(&self) -> Result<PathBuf, Error> {
Ok(self.app_dir.join(".cache/"))
pub fn cache_dir(&self) -> Result<PathBuf> {
let cache_dir = self.app_dir.join(".cache/");
std::fs::create_dir_all(&cache_dir)?;
Ok(cache_dir)
}

pub fn build_log_dir(&self) -> Result<PathBuf, Error> {
Ok(self.app_dir.join(".cache/log/"))
pub fn build_log_dir(&self) -> Result<PathBuf> {
let build_log_dir = self.app_dir.join(".cache/log/");
std::fs::create_dir_all(&build_log_dir)?;
Ok(build_log_dir)
}

/// Creates the build log if it isn't created already, returns relative path from app_dir to log directory
pub async fn create_build_log(&self) -> Result<PathBuf, Error> {
pub async fn create_build_log(&self) -> Result<PathBuf> {
let log_dir = Self::build_log_dir(self)?;
if !log_dir.exists() {
tokio::fs::create_dir_all(&log_dir)
.await
.map_err(|e| Error::GenericErr(e.to_string()))?;
tokio::fs::create_dir_all(&log_dir).await?;
}

Ok(log_dir)
}

pub async fn log_build(&self, is_enclave: bool) -> Result<(), Error> {
pub async fn log_build(&self, is_enclave: bool) -> Result<()> {
let log_dir = Self::create_build_log(self).await?;

let filename = match is_enclave {
true => "enclave",
false => "contract",
};

tokio::fs::write(log_dir.join(filename), "test")
.await
.map_err(|e| Error::GenericErr(e.to_string()))?;
tokio::fs::write(log_dir.join(filename), "log").await?;

Ok(())
}
Expand Down
2 changes: 1 addition & 1 deletion crates/cli/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ fn default_ws_url() -> Url {
}

fn default_grpc_url() -> Url {
"http://127.0.0.1:9090,"
"http://127.0.0.1:9090"
.parse()
.expect("valid hardcoded URL")
}
Expand Down
58 changes: 0 additions & 58 deletions crates/cli/src/error.rs

This file was deleted.

15 changes: 4 additions & 11 deletions crates/cli/src/handler.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use async_trait::async_trait;
use color_eyre::{Report, Result};

use crate::{config::Config, error::Error, request::Request, response::Response};
use crate::{config::Config, request::Request, response::Response};

pub mod utils;
// commands
Expand All @@ -14,24 +15,16 @@ pub mod init;

#[async_trait]
pub trait Handler {
type Error;
type Response;

async fn handle<C: AsRef<Config> + Send>(
self,
config: C,
) -> Result<Self::Response, Self::Error>;
async fn handle<C: AsRef<Config> + Send>(self, config: C) -> Result<Self::Response, Report>;
}

#[async_trait]
impl Handler for Request {
type Error = Error;
type Response = Response;

async fn handle<C: AsRef<Config> + Send>(
self,
config: C,
) -> Result<Self::Response, Self::Error> {
async fn handle<C: AsRef<Config> + Send>(self, config: C) -> Result<Self::Response, Report> {
match self {
Request::Init(request) => request.handle(config).await,
Request::Handshake(request) => request.handle(config).await,
Expand Down
18 changes: 4 additions & 14 deletions crates/cli/src/handler/contract_build.rs
Original file line number Diff line number Diff line change
@@ -1,26 +1,21 @@
use std::process::Command;

use async_trait::async_trait;
use color_eyre::owo_colors::OwoColorize;
use color_eyre::{eyre::eyre, owo_colors::OwoColorize, Report, Result};
use tracing::{debug, info};

use crate::{
config::Config,
error::Error,
handler::Handler,
request::contract_build::ContractBuildRequest,
response::{contract_build::ContractBuildResponse, Response},
};

#[async_trait]
impl Handler for ContractBuildRequest {
type Error = Error;
type Response = Response;

async fn handle<C: AsRef<Config> + Send>(
self,
config: C,
) -> Result<Self::Response, Self::Error> {
async fn handle<C: AsRef<Config> + Send>(self, config: C) -> Result<Self::Response, Report> {
let config = config.as_ref();
info!("{}", "\nPeforming Contract Build".blue().bold());

Expand All @@ -46,15 +41,10 @@ impl Handler for ContractBuildRequest {
}

info!("{}", "🚧 Building contract binary ...".green().bold());
let status = command
.status()
.map_err(|e| Error::GenericErr(e.to_string()))?;
let status = command.status()?;

if !status.success() {
return Err(Error::GenericErr(format!(
"Couldn't build contract. \n{:?}",
status
)));
return Err(eyre!("Couldn't build contract. \n{:?}", status));
}

config.log_build(false).await?;
Expand Down
Loading
Loading