Implementing a basic classic try-catch in Zig - struct

How do I implement the classic try-catch error handling in Zig?
For example. How to solve this error and only execute append when no error occurs?
var stmt = self.statement() catch {
self.synchronize(); // Only execute this when there is an error.
};
self.top_level.statements.append(stmt); // HELP? This should only be executed when no error
// ...
fn synchronize() void {
// ...implementation
}
fn statement() SomeError!void {
// ...implementation
}
If possible please show a modified version of the above code.

Try an if-else, as follows:
if (self.statement()) |stmt| {
// HELP? This should only be executed when no error
self.top_level.statements.append(stmt)
} else |error| {
// Only execute this when there is an error.
self.synchronize()
}
You can learn more about if in the zig documentation

Related

How to properly handle a tokio::try_join! if one of the tasks panics and cleanly abort?

For the two async functions that I am passing to my try_join!(), let's say there's 3 ways that they could panic.
I'm trying to use a set_hook to catch the errors but I'm not sure how to do a match statement on the panics so I can display a custom error message for each of the ways that they can panic. It looks like set_hook takes a Box(Any) (?), so I was wondering if there was a way to check the type of Error. Basically I just don't want to do regex on the ErrString.
I'm also not sure what the best way to abort the runtime within each match branch. I'm currently using std::process::exit(0).
code looks like:
set_hook(Box::new(|panic_info| {
println!("Thread panicked! {}", panic_info);
// std::process::exit(0);
}));
let (result1, result2) = tokio::try_join!(func1, func2); // code that could panic
I want to be able to do something like
set_hook(Box::new(|panic_info| {
match panic_info {
panic_type_1 => { println!("X was invalid, please try using valid X") }
panic_type_2 => { println!("Y was invalid, please try using valid Y") }
panic_type_3 => { println!("Z was invalid, please try using valid Z") }
_ => { println!("Something else happened: {}", panic_info) }
}
}));
let (result1, result2) = tokio::try_join!(func1, func2); // code that could panic
Don't bother with set_hook. The future that tokio::task::spawn* returns resolves to a Result with a JoinError type, which has a [try_]into_panic to get the boxed object that was passed to panic.
The panic message is stored as a Box<dyn Any> which has tons of methods for downcasting it into various types.

How do I prevent res.sendFile('/404.html') from redirecting the current path to /404.html?

I am using express 4.x to handle an error:
try {
// ... normal logic
} catch (error) {
// error logic
return res.status(404).sendFile('/404.html');
}
When the user visits a non-existed path, like https://example.com/not-exist
I want the user to stay on that path /not-exist.
But it's not happening. Instead, the browser redirects me to /404.html, so what's in the address bar is: https://example.com/404.html
Is there any way to prevent this from happening?
You must specify the root when calling sendFile. This code works for me:
try {
// ... normal logic
} catch (error) {
// error logic
return res.status(404).sendFile(process.cwd()+'/404.html');
}
However, if you want a shorter but deprecated approach, you can use sendfile.
try {
// ... normal logic
} catch (error) {
// error logic
return res.status(404).sendfile('./404.html');
}
The difference between the non-deprecated and deprecated approach is the capitalisation of file. I recommend you only use sendFile.
Try __dirname
try {
// ... normal logic
} catch (error) {
// error logic
return res.status(404).sendFile(path.join('__dirname', '404.html'));
}

Getting current path when handling rejections

I'd like to know how it would be possible to get HTTP path in Warp's rejection handler? I've got the following rejection method:
pub(crate) async fn handle(err: Rejection) -> Result<impl Reply, Infallible> {
let response = if err.is_not_found() {
HttpApiProblem::with_title_and_type_from_status(StatusCode::NOT_FOUND)
} else if let Some(e) = err.find::<warp::filters::body::BodyDeserializeError>() {
HttpApiProblem::with_title_and_type_from_status(StatusCode::BAD_REQUEST)
.set_detail(format!("{}", e))
} else if let Some(e) = err.find::<Error>() {
handle_request_error(e)
} else if let Some(e) = err.find::<warp::reject::MethodNotAllowed>() {
HttpApiProblem::with_title_and_type_from_status(StatusCode::METHOD_NOT_ALLOWED)
.set_detail(format!("{}", e))
} else {
error!("handle_rejection catch all: {:?}", err);
HttpApiProblem::with_title_and_type_from_status(StatusCode::INTERNAL_SERVER_ERROR)
};
Ok(response.to_hyper_response())
}
For instance, I'd call curl localhost:1234/this-aint-valid-path/123 and would like to have access to /this-aint-valid-path/123 for logging purposes as well as returning this as part of the error response.
It loos like the method err.is_not_found() checks whether the reason matches Reason::NotFound, which is an enumeration variant with no parameters. Rejection structs have no additional metadata beyond their reason, so the code in your question cannot be modified to solve your problem. It is however possible to create a custom reason with whatever metadata you want. The method you're looking for to create that Rejection object is called custom, and the docs for it can be found here.

Is there an event to see if an error has been fired?

I’m just trying to know how, so I can make my discord.js bot detect errors and send it to me.
Please provide the code module where you would like to handle this error.
Seems that you're looking to use javascript's try...catch code block syntax. It goes like this:
"use strict";
try {
// Your buggy code:
let result = 2 + "2";
} catch (e) {
// Your instructions if an <e> error occurs
console.log(e);
}
I cannot know what you mean by
[...] "errors and send it to me."
How would you like the client to send this errors to you? Please try being more specific next time. I hope console.log does it for you.
You can catch the error from the promise returned by an action, e.g.
message.channel.send('Hello').catch(e => {
// do error handling here
console.log(e)
})

integrating validation module in node.js

I am using the following node module for validation: https://github.com/chriso/node-validator
Now, suppose I want to check on an user input like this check('abc').isInt(); I noticed that it basically throws an error!
I am pretty new with node.js but it seems to me that having to use try{}catch(e){} blocks every time I need to check on a user input is a bit on an overkill.
wouldn't it make more sense to have something like
if (check('abc').isInt()) {
// Do things here
next(null, stuff_I_want_to_return)
} else next(error);
instead of
try{
check('abc').isInt()
next(null, stuff_I_want_to_return)
} catch(e) { next(e); }
?? I have no idea, please clarify on what is the best approach to have in this case. Thanks in advance.
Their docs say you can do this
var Validator = require('validator').Validator;
var v = new Validator();
v.error = function(msg) {
console.log('Fail');
}
v.check('abc').isInt(); //'Fail'
That way you won't have to do try catch
Check module core-util-is providing functions introduced in Node v0.12.
In your case, method isNumber would be helpful
It's still fairly common in Node.js for synchronous functions to throw as they don't usually have a callback to pass an error to. But, they still need some way to deliver it to calling code and return error; would generally be an unexpected choice.
Though, the documentation for node-validator does include an example for extending Validators with a getErrors() method under "Error Handling."
Validator.prototype.error = function (msg) {
this._errors.push(msg);
return this;
}
Validator.prototype.getErrors = function () {
return this._errors;
}
Which could be used to report errors without throw:
var validator = new Validator();
if (validator.check('abc').isInt()) {
next(null, ...);
} else {
next(validator.getErrors());
}
Note: The _errors property should already be defined after using .check().

Resources