Skip to content
This repository has been archived by the owner on Aug 3, 2023. It is now read-only.

Fixed issue with tail not deserailzing event properly #1994

Merged
merged 5 commits into from
Jul 15, 2021
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
29 changes: 26 additions & 3 deletions Cargo.lock

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

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@ backtrace = { version = "0.3.58" }
base64 = "0.13.0"
billboard = "0.1.0"
binary-install = "0.0.3-alpha.1"
chrome-devtools-rs = { version = "=0.0.0-alpha.1", features = ["color"] }
chrome-devtools-rs = { version = "0.0.0-alpha.3", features = ["color"] }
chrono = "0.4.19"
clap = "2.33.3"
cloudflare = "0.8.3"
colored_json = "2.1.0"
config = "0.11.0"
console = "0.14.1"
dirs = "3.0.1"
Expand Down
56 changes: 42 additions & 14 deletions src/commands/dev/socket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ use futures_util::sink::SinkExt;
use futures_util::stream::{SplitStream, StreamExt};
use tokio_stream::wrappers::UnboundedReceiverStream;

use crate::terminal::colored_json_string;
use crate::terminal::message::{Message, StdErr, StdOut};
use protocol::domain::runtime::event::Event::ExceptionThrown;
use tokio::net::TcpStream;
use tokio::sync::mpsc;
use tokio::time::sleep;
Expand Down Expand Up @@ -97,6 +99,18 @@ async fn connect_retry(socket_url: &Url) -> WebSocketStream<MaybeTlsStream<TcpSt
}
}

fn print_json(value: Result<serde_json::Value, serde_json::Error>, fallback: String) {
if let Ok(json) = value {
if let Ok(json_str) = colored_json_string(&json) {
println!("{}", json_str);
} else {
StdOut::message(fallback.as_str());
}
} else {
println!("{}", fallback);
}
}

async fn print_ws_messages(
mut read: SplitStream<WebSocketStream<MaybeTlsStream<TcpStream>>>,
) -> Result<()> {
Expand All @@ -107,21 +121,35 @@ async fn print_ws_messages(
log::info!("{}", &message_text);

let parsed_message: Result<protocol::Runtime> = serde_json::from_str(&message_text)
.map_err(|e| anyhow!("this event could not be parsed:\n{}", e));

if let Ok(protocol::Runtime::Event(event)) = parsed_message {
// Try to parse json to pretty print, otherwise just print string
let json_parse: Result<serde_json::Value, serde_json::Error> =
serde_json::from_str(&*event.to_string());
if let Ok(json) = json_parse {
if let Ok(json_str) = serde_json::to_string_pretty(&json) {
println!("{}", json_str);
} else {
StdOut::message(&format!("{:?}", event.to_string()));
}
} else {
println!("{}", event);
.map_err(|e| anyhow!("Failed to parse event:\n{}", e));

match parsed_message {
Ok(protocol::Runtime::Event(ExceptionThrown(params))) => {
let default_description = "N/A".to_string();
let description = params
.exception_details
.exception
.description
.as_ref()
.unwrap_or(&default_description);

StdOut::message(&format!(
"{} at line {:?}, col {:?}",
description,
params.exception_details.line_number,
params.exception_details.column_number,
));

let json_parse = serde_json::to_value(params.clone());
print_json(json_parse, format!("{:?}", params));
}
Ok(protocol::Runtime::Event(event)) => {
// Try to parse json to pretty print, otherwise just print string
let json_parse: Result<serde_json::Value, serde_json::Error> =
serde_json::from_str(&*event.to_string());
print_json(json_parse, event.to_string());
}
_ => {}
}
}
Err(error) => return Err(error.into()),
Expand Down
76 changes: 36 additions & 40 deletions src/tail/log_server.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::terminal::{emoji, styles};
use crate::terminal::{colored_json_string, emoji, styles};
use anyhow::Result;
use hyper::server::conn::AddrIncoming;
use hyper::server::Builder;
Expand Down Expand Up @@ -31,54 +31,45 @@ impl LogServer {
}

pub async fn run(self) -> Result<()> {
// this is so bad
// but i also am so bad at types
// TODO: make this less terrible
match self.format.as_str() {
"json" => {
let service = make_service_fn(|_| async {
Ok::<_, hyper::Error>(service_fn(print_logs_json))
});

let server = self.server.serve(service);

// The shutdown receiver listens for a one shot message from our sigint handler as a signal
// to gracefully shut down the hyper server.
let shutdown_rx = self.shutdown_rx;
let format = self.format;

let graceful = server.with_graceful_shutdown(async {
shutdown_rx.await.ok();
});
let server_fn_gen = |format: String| {
service_fn(move |req: Request<Body>| {
let format = format.clone();
print_logs(req, format)
})
};

graceful.await?;
let service = make_service_fn(move |_| {
let format = format.clone();
async move { Ok::<_, hyper::Error>(server_fn_gen(format)) }
});

Ok(())
}
"pretty" => {
let service = make_service_fn(|_| async {
Ok::<_, hyper::Error>(service_fn(print_logs_pretty))
});
let server = self.server.serve(service);

let server = self.server.serve(service);
// The shutdown receiver listens for a one shot message from our sigint handler as a signal
// to gracefully shut down the hyper server.
let shutdown_rx = self.shutdown_rx;

// The shutdown receiver listens for a one shot message from our sigint handler as a signal
// to gracefully shut down the hyper server.
let shutdown_rx = self.shutdown_rx;
let graceful = server.with_graceful_shutdown(async {
shutdown_rx.await.ok();
});

let graceful = server.with_graceful_shutdown(async {
shutdown_rx.await.ok();
});
graceful.await?;

graceful.await?;
Ok(())
}
}

Ok(())
}
_ => unreachable!(),
}
async fn print_logs(req: Request<Body>, format: String) -> Result<Response<Body>> {
match format.as_str() {
"pretty" => print_logs_pretty(req).await,
"json" => print_logs_json(req).await,
_ => unreachable!(),
}
}

async fn print_logs_json(req: Request<Body>) -> Result<Response<Body>, hyper::Error> {
async fn print_logs_json(req: Request<Body>) -> Result<Response<Body>> {
match (req.method(), req.uri().path()) {
(&Method::POST, "/") => {
let whole_body = hyper::body::to_bytes(req.into_body()).await?;
Expand Down Expand Up @@ -137,7 +128,12 @@ async fn print_logs_pretty(req: Request<Body>) -> Result<Response<Body>> {
if !parsed.logs.is_empty() {
println!(" Logs:");
parsed.logs.iter().for_each(|log| {
let messages = log.message.join(" ");
let message = colored_json_string(&log.message);
let messages = if let Ok(m) = message {
m
} else {
"Error: Failed to convert encoded message to string".to_string()
};

let output = match log.level.as_str() {
"assert" | "error" => format!("{} {}", emoji::X, styles::warning(messages)),
Expand Down Expand Up @@ -183,7 +179,7 @@ struct LogException {

#[derive(Debug, Serialize, Deserialize)]
struct LogMessage {
message: Vec<String>,
message: serde_json::Value,
jspspike marked this conversation as resolved.
Show resolved Hide resolved
level: String,
timestamp: usize,
}
Expand Down
19 changes: 19 additions & 0 deletions src/terminal/json.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
use colored_json::{Color, ColoredFormatter, PrettyFormatter, Styler};

pub fn colored_json_string(value: &serde_json::Value) -> Result<String, serde_json::Error> {
let formatter = ColoredFormatter::with_styler(
PrettyFormatter::new(),
Styler {
key: Color::Green.normal(),
string_value: Color::Blue.bold(),
integer_value: Color::Purple.bold(),
float_value: Color::Purple.italic(),
object_brackets: Color::Yellow.bold(),
array_brackets: Color::Cyan.bold(),
bool_value: Color::Red.bold(),
..Default::default()
caass marked this conversation as resolved.
Show resolved Hide resolved
},
);

formatter.to_colored_json_auto(&value)
}
2 changes: 2 additions & 0 deletions src/terminal/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
mod browser;
pub mod emoji;
pub mod interactive;
mod json;
pub mod message;
pub mod styles;
pub use browser::open_browser;
pub use json::colored_json_string;