Make route collisions a hard error.

This is a breaking change. Previously, route collisions were warnings.
This commit is contained in:
Sergio Benitez 2017-04-18 17:42:44 -07:00
parent f97b02dda6
commit d6e86be1b0
4 changed files with 22 additions and 5 deletions

View File

@ -21,6 +21,7 @@ fn not_found(req: &rocket::Request) -> content::HTML<String> {
fn main() { fn main() {
let e = rocket::ignite() let e = rocket::ignite()
// .mount("/", routes![hello, hello]) // uncoment this to get an error
.mount("/", routes![hello]) .mount("/", routes![hello])
.catch(errors![not_found]) .catch(errors![not_found])
.launch(); .launch();

View File

@ -23,11 +23,14 @@ pub enum Error {
/// The kind of launch error that occured. /// The kind of launch error that occured.
/// ///
/// In almost every instance, a launch error occurs because of an I/O error; /// In almost every instance, a launch error occurs because of an I/O error;
/// this represented by the `Io` variant. The `Unknown` variant captures all /// this is represented by the `Io` variant. A launch error may also occur
/// other kinds of launch errors. /// because of ill-defined routes that lead to collisions; this is represented
/// by the `Collision` variant. The `Unknown` variant captures all other kinds
/// of launch errors.
#[derive(Debug)] #[derive(Debug)]
pub enum LaunchErrorKind { pub enum LaunchErrorKind {
Io(io::Error), Io(io::Error),
Collision,
Unknown(Box<::std::error::Error + Send + Sync>) Unknown(Box<::std::error::Error + Send + Sync>)
} }
@ -110,6 +113,13 @@ impl LaunchError {
} }
} }
impl From<LaunchErrorKind> for LaunchError {
#[inline]
fn from(kind: LaunchErrorKind) -> LaunchError {
LaunchError::new(kind)
}
}
impl From<hyper::Error> for LaunchError { impl From<hyper::Error> for LaunchError {
#[inline] #[inline]
fn from(error: hyper::Error) -> LaunchError { fn from(error: hyper::Error) -> LaunchError {
@ -125,6 +135,7 @@ impl fmt::Display for LaunchErrorKind {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self { match *self {
LaunchErrorKind::Io(ref e) => write!(f, "I/O error: {}", e), LaunchErrorKind::Io(ref e) => write!(f, "I/O error: {}", e),
LaunchErrorKind::Collision => write!(f, "route collisions detected"),
LaunchErrorKind::Unknown(ref e) => write!(f, "unknown error: {}", e) LaunchErrorKind::Unknown(ref e) => write!(f, "unknown error: {}", e)
} }
} }
@ -152,6 +163,7 @@ impl ::std::error::Error for LaunchError {
self.mark_handled(); self.mark_handled();
match *self.kind() { match *self.kind() {
LaunchErrorKind::Io(_) => "an I/O error occured during launch", LaunchErrorKind::Io(_) => "an I/O error occured during launch",
LaunchErrorKind::Collision => "route collisions were detected",
LaunchErrorKind::Unknown(_) => "an unknown error occured during launch" LaunchErrorKind::Unknown(_) => "an unknown error occured during launch"
} }
} }
@ -168,6 +180,10 @@ impl Drop for LaunchError {
error!("Rocket failed to launch due to an I/O error."); error!("Rocket failed to launch due to an I/O error.");
panic!("{}", e); panic!("{}", e);
} }
LaunchErrorKind::Collision => {
error!("Rocket failed to launch due to routing collisions.");
panic!("route collisions detected");
}
LaunchErrorKind::Unknown(ref e) => { LaunchErrorKind::Unknown(ref e) => {
error!("Rocket failed to launch due to an unknown error."); error!("Rocket failed to launch due to an unknown error.");
panic!("{}", e); panic!("{}", e);

View File

@ -18,7 +18,7 @@ use response::{Body, Response};
use router::{Router, Route}; use router::{Router, Route};
use catcher::{self, Catcher}; use catcher::{self, Catcher};
use outcome::Outcome; use outcome::Outcome;
use error::{Error, LaunchError}; use error::{Error, LaunchError, LaunchErrorKind};
use http::{Method, Status, Header, Session}; use http::{Method, Status, Header, Session};
use http::hyper::{self, header}; use http::hyper::{self, header};
@ -596,7 +596,7 @@ impl Rocket {
/// ``` /// ```
pub fn launch(self) -> LaunchError { pub fn launch(self) -> LaunchError {
if self.router.has_collisions() { if self.router.has_collisions() {
warn!("Route collisions detected!"); return LaunchError::from(LaunchErrorKind::Collision);
} }
let full_addr = format!("{}:{}", self.config.address, self.config.port); let full_addr = format!("{}:{}", self.config.address, self.config.port);

View File

@ -51,7 +51,7 @@ impl Router {
for b_route in routes.iter().skip(i + 1) { for b_route in routes.iter().skip(i + 1) {
if a_route.collides_with(b_route) { if a_route.collides_with(b_route) {
result = true; result = true;
warn!("{} and {} collide!", a_route, b_route); error!("{} and {} collide!", a_route, b_route);
} }
} }
} }