Repository: AlexPikalov/cdrs (language: rust)

Issue:
Revise unwraps
We need to rid of as many unwraps as possible to avoid panic.


Discussion / hints:
in addition find_by_name returns: Option<Result> which is a little cumbersome IMO, Option should be enough to cover both cases

P.S. did a little benchmark of this crate vs https://github.com/tupshin/cassandra-rs (C++ wrapper)
```bash
running 2 tests
test bench_c_driver    ... bench:  15,921,280 ns/iter (+/- 9,756,013)
test bench_rust_driver ... bench:     848,061 ns/iter (+/- 505,422)
```

looks very promising !
@ernestas-poskus 
It sounds encouraging.
As for find_by_name. Do you mean this one?https://github.com/AlexPikalov/cdrs/blob/master/src/types/mod.rs#L29?

If so, it appears for me reasonable to return `Option` in a same way as it is in [HashMap](https://doc.rust-lang.org/std/collections/struct.HashMap.html#method.get)
We might want to revisit unreachables!() . That macro results in thread panicking. I have stumbled upon panicking at least thrice. So as a better practice it would be better to return errror::Error
@harrydevnull I agree that this approach should be revisited. They were used in those places which, as I assumed, won't be reached due to protocol specification. For instance, Version can be either `0x04` or `0x84`. Most probably in some cases this assumption was wrong.

I'll create a super-task to add tests to each module. There we could track progress.

Fix patch:
diff --git a/README.md b/README.md
index e0fdd89..5960da6 100644
--- a/README.md
+++ b/README.md
@@ -278,7 +278,7 @@ into appropriate Rust type:
 ```rust
 use cdrs::error::{Result as CResult};
 
-let res_body = parsed.get_body();
+let res_body = parsed.get_body().unwrap();
 let rows = res_body.into_rows().unwrap();
 let messages: Vec<CResult<Message>> = rows
     .iter()
@@ -303,7 +303,7 @@ struct Author {
 
 //...
 use cdrs::error::{Result as CResult};
-let res_body = parsed.get_body();
+let res_body = parsed.get_body().unwrap();
 let rows = res_body.into_rows().unwrap();
 let messages: Vec<CAuthor> = rows
     .iter()
@@ -345,6 +345,7 @@ Prepare-execute query is also supported:
   let executed = session.execute(query_id, execution_params, false, false)
     .unwrap()
     .get_body()
+    .unwrap()
     .into_set_keyspace()
     .unwrap();
 ```
diff --git a/examples/all.rs b/examples/all.rs
index 7be1ac7..a2025f5 100644
--- a/examples/all.rs
+++ b/examples/all.rs
@@ -237,6 +237,7 @@ fn prepare_query(session: &mut Session<NoneAuthenticator, TransportTcp>,
         .prepare(query.to_string(), false, false)
         .unwrap()
         .get_body()
+        .unwrap()
         .into_prepared()
         .unwrap()
         .id
@@ -270,6 +271,7 @@ fn select_all_ints(session: &mut Session<NoneAuthenticator, TransportTcp>) -> bo
         .query(select_query, false, false)
         .unwrap()
         .get_body()
+        .unwrap()
         .into_rows()
         .unwrap();
 
@@ -339,6 +341,7 @@ fn select_table_str(session: &mut Session<NoneAuthenticator, TransportTcp>) -> b
         .query(select_query, false, false)
         .unwrap()
         .get_body()
+        .unwrap()
         .into_rows()
         .unwrap();
 
@@ -388,6 +391,7 @@ fn select_table_list(session: &mut Session<NoneAuthenticator, TransportTcp>) ->
         .query(select_query, false, false)
         .unwrap()
         .get_body()
+        .unwrap()
         .into_rows()
         .unwrap();
 
@@ -459,6 +463,7 @@ fn select_table_map(session: &mut Session<NoneAuthenticator, TransportTcp>) -> b
         .query(select_query, false, false)
         .unwrap()
         .get_body()
+        .unwrap()
         .into_rows()
         .unwrap();
 
@@ -533,6 +538,7 @@ fn select_table_udt(session: &mut Session<NoneAuthenticator, TransportTcp>) -> b
         .query(select_query, false, false)
         .unwrap()
         .get_body()
+        .unwrap()
         .into_rows()
         .unwrap();
 
@@ -570,6 +576,7 @@ fn select_table_bool(session: &mut Session<NoneAuthenticator, TransportTcp>) ->
         .query(select_query, false, false)
         .unwrap()
         .get_body()
+        .unwrap()
         .into_rows()
         .unwrap();
 
@@ -609,6 +616,7 @@ fn select_table_uuid(session: &mut Session<NoneAuthenticator, TransportTcp>) ->
         .query(select_query, false, false)
         .unwrap()
         .get_body()
+        .unwrap()
         .into_rows()
         .unwrap();
 
@@ -647,6 +655,7 @@ fn select_table_float(session: &mut Session<NoneAuthenticator, TransportTcp>) ->
         .query(select_query, false, false)
         .unwrap()
         .get_body()
+        .unwrap()
         .into_rows()
         .unwrap();
 
@@ -686,6 +695,7 @@ fn select_table_blob(session: &mut Session<NoneAuthenticator, TransportTcp>) ->
         .query(select_query, false, false)
         .unwrap()
         .get_body()
+        .unwrap()
         .into_rows()
         .unwrap();
 
diff --git a/examples/batch_queries.rs b/examples/batch_queries.rs
index f35e501..919b0d8 100644
--- a/examples/batch_queries.rs
+++ b/examples/batch_queries.rs
@@ -30,6 +30,7 @@ fn main() {
         .prepare(prepare_query, with_tracing, with_warnings)
         .unwrap()
         .get_body()
+        .unwrap()
         .into_prepared()
         .unwrap();
 
diff --git a/examples/prepare_execute.rs b/examples/prepare_execute.rs
index 1b1f788..b9420b5 100644
--- a/examples/prepare_execute.rs
+++ b/examples/prepare_execute.rs
@@ -28,6 +28,7 @@ fn main() {
         .prepare(create_table_cql, with_tracing, with_warnings)
         .unwrap()
         .get_body()
+        .unwrap()
         .into_prepared()
         .unwrap();
 
@@ -39,6 +40,7 @@ fn main() {
         .execute(query_id, execution_params, false, false)
         .unwrap()
         .get_body()
+        .unwrap()
         .into_set_keyspace()
         .unwrap();
 
diff --git a/examples/read_table_into_struct.rs b/examples/read_table_into_struct.rs
index b56d7be..da8ad04 100644
--- a/examples/read_table_into_struct.rs
+++ b/examples/read_table_into_struct.rs
@@ -59,7 +59,7 @@ fn main() {
 
             match query_op {
                 Ok(res) => {
-                    let res_body = res.get_body();
+                    let res_body = res.get_body().unwrap();
                     if let Some(rows) = res_body.into_rows() {
                         let employees: Vec<Employee> = rows.iter()
                             .map(|row| {
diff --git a/examples/simple.rs b/examples/simple.rs
index 03f18e1..e2f55fb 100644
--- a/examples/simple.rs
+++ b/examples/simple.rs
@@ -60,7 +60,7 @@ fn main() {
             match query_op {
                 Ok(res) => {
                     let res_body = res.get_body();
-                    if let Some(rows) = res_body.into_rows() {
+                    if let Some(rows) = res_body.unwrap().into_rows() {
                         let employees: Vec<Employee> = rows.iter()
                             .map(|row| {
                                 let mut employee = Employee { ..Default::default() };
diff --git a/src/client.rs b/src/client.rs
index a4b9e3a..2d421f0 100644
--- a/src/client.rs
+++ b/src/client.rs
@@ -54,7 +54,7 @@ impl<'a, T: Authenticator + 'a, X: CDRSTransport + 'a> CDRS<T, X> {
         parse_frame(&mut self.transport, &self.compressor)
         .map(|frame| {
                 match frame.get_body() {
-                ResponseBody::Supported(ref supported_body) => supported_body.data.clone(),
+                Ok(ResponseBody::Supported(ref supported_body)) => supported_body.data.clone(),
                 _ => unreachable!(),
             }
         })
@@ -79,7 +79,7 @@ impl<'a, T: Authenticator + 'a, X: CDRSTransport + 'a> CDRS<T, X> {
         }
 
         if start_response.opcode == Opcode::Authenticate {
-            let body = start_response.get_body();
+            let body = start_response.get_body()?;
             let authenticator =
                 body.get_authenticator()
                     .expect("Cassandra Server did communicate that it needed password
diff --git a/src/consistency.rs b/src/consistency.rs
index b9f6bec..6516817 100644
--- a/src/consistency.rs
+++ b/src/consistency.rs
@@ -3,9 +3,10 @@
 use std::io;
 use std::convert::From;
 use std::default::Default;
-use super::{IntoBytes, FromCursor};
-use super::types::*;
-use super::FromBytes;
+
+use {IntoBytes, FromCursor, FromBytes};
+use error;
+use types::*;
 
 /// `Consistency` is an enum which represents Cassandra's consistency levels.
 /// To find more details about each consistency level please refer to Cassandra official docs.
@@ -99,46 +100,48 @@ impl IntoBytes for Consistency {
 
 impl From<i32> for Consistency {
     fn from(bytes: i32) -> Consistency {
-        return match bytes {
-                   0x0000 => Consistency::Any,
-                   0x0001 => Consistency::One,
-                   0x0002 => Consistency::Two,
-                   0x0003 => Consistency::Three,
-                   0x0004 => Consistency::Quorum,
-                   0x0005 => Consistency::All,
-                   0x0006 => Consistency::LocalQuorum,
-                   0x0007 => Consistency::EachQuorum,
-                   0x0008 => Consistency::Serial,
-                   0x0009 => Consistency::LocalSerial,
-                   0x000A => Consistency::LocalOne,
-                   _ => Consistency::Unknown,
-               };
+        match bytes {
+            0x0000 => Consistency::Any,
+            0x0001 => Consistency::One,
+            0x0002 => Consistency::Two,
+            0x0003 => Consistency::Three,
+            0x0004 => Consistency::Quorum,
+            0x0005 => Consistency::All,
+            0x0006 => Consistency::LocalQuorum,
+            0x0007 => Consistency::EachQuorum,
+            0x0008 => Consistency::Serial,
+            0x0009 => Consistency::LocalSerial,
+            0x000A => Consistency::LocalOne,
+            _ => Consistency::Unknown,
+        }
     }
 }
 
 impl FromBytes for Consistency {
-    fn from_bytes(bytes: &[u8]) -> Consistency {
-        return match from_bytes(bytes) {
-                   0x0000 => Consistency::Any,
-                   0x0001 => Consistency::One,
-                   0x0002 => Consistency::Two,
-                   0x0003 => Consistency::Three,
-                   0x0004 => Consistency::Quorum,
-                   0x0005 => Consistency::All,
-                   0x0006 => Consistency::LocalQuorum,
-                   0x0007 => Consistency::EachQuorum,
-                   0x0008 => Consistency::Serial,
-                   0x0009 => Consistency::LocalSerial,
-                   0x000A => Consistency::LocalOne,
-                   _ => Consistency::Unknown,
-               };
+    fn from_bytes(bytes: &[u8]) -> error::Result<Consistency> {
+        try_from_bytes(bytes)
+            .map_err(Into::into)
+            .map(|b| match b {
+                     0x0000 => Consistency::Any,
+                     0x0001 => Consistency::One,
+                     0x0002 => Consistency::Two,
+                     0x0003 => Consistency::Three,
+                     0x0004 => Consistency::Quorum,
+                     0x0005 => Consistency::All,
+                     0x0006 => Consistency::LocalQuorum,
+                     0x0007 => Consistency::EachQuorum,
+                     0x0008 => Consistency::Serial,
+                     0x0009 => Consistency::LocalSerial,
+                     0x000A => Consistency::LocalOne,
+                     _ => Consistency::Unknown,
+                 })
     }
 }
 
 impl FromCursor for Consistency {
-    fn from_cursor(mut cursor: &mut io::Cursor<&[u8]>) -> Consistency {
-        let consistency_num = CIntShort::from_cursor(&mut cursor) as i32;
-        return Consistency::from(consistency_num);
+    fn from_cursor(mut cursor: &mut io::Cursor<&[u8]>) -> error::Result<Consistency> {
+        let consistency_num = CIntShort::from_cursor(&mut cursor)? as i32;
+        Ok(Consistency::from(consistency_num))
     }
 }
 
@@ -184,43 +187,51 @@ mod tests {
 
     #[test]
     fn test_consistency_from_bytes() {
-        assert_eq!(Consistency::from_bytes(&[0, 0]), Consistency::Any);
-        assert_eq!(Consistency::from_bytes(&[0, 1]), Consistency::One);
-        assert_eq!(Consistency::from_bytes(&[0, 2]), Consistency::Two);
-        assert_eq!(Consistency::from_bytes(&[0, 3]), Consistency::Three);
-        assert_eq!(Consistency::from_bytes(&[0, 4]), Consistency::Quorum);
-        assert_eq!(Consistency::from_bytes(&[0, 5]), Consistency::All);
-        assert_eq!(Consistency::from_bytes(&[0, 6]), Consistency::LocalQuorum);
-        assert_eq!(Consistency::from_bytes(&[0, 7]), Consistency::EachQuorum);
-        assert_eq!(Consistency::from_bytes(&[0, 8]), Consistency::Serial);
-        assert_eq!(Consistency::from_bytes(&[0, 9]), Consistency::LocalSerial);
-        assert_eq!(Consistency::from_bytes(&[0, 10]), Consistency::LocalOne);
-        assert_eq!(Consistency::from_bytes(&[0, 11]), Consistency::Unknown);
+        assert_eq!(Consistency::from_bytes(&[0, 0]).unwrap(), Consistency::Any);
+        assert_eq!(Consistency::from_bytes(&[0, 1]).unwrap(), Consistency::One);
+        assert_eq!(Consistency::from_bytes(&[0, 2]).unwrap(), Consistency::Two);
+        assert_eq!(Consistency::from_bytes(&[0, 3]).unwrap(),
+                   Consistency::Three);
+        assert_eq!(Consistency::from_bytes(&[0, 4]).unwrap(),
+                   Consistency::Quorum);
+        assert_eq!(Consistency::from_bytes(&[0, 5]).unwrap(), Consistency::All);
+        assert_eq!(Consistency::from_bytes(&[0, 6]).unwrap(),
+                   Consistency::LocalQuorum);
+        assert_eq!(Consistency::from_bytes(&[0, 7]).unwrap(),
+                   Consistency::EachQuorum);
+        assert_eq!(Consistency::from_bytes(&[0, 8]).unwrap(),
+                   Consistency::Serial);
+        assert_eq!(Consistency::from_bytes(&[0, 9]).unwrap(),
+                   Consistency::LocalSerial);
+        assert_eq!(Consistency::from_bytes(&[0, 10]).unwrap(),
+                   Consistency::LocalOne);
+        assert_eq!(Consistency::from_bytes(&[0, 11]).unwrap(),
+                   Consistency::Unknown);
     }
 
     #[test]
     fn test_consistency_from_cursor() {
-        assert_eq!(Consistency::from_cursor(&mut Cursor::new(&[0, 0])),
+        assert_eq!(Consistency::from_cursor(&mut Cursor::new(&[0, 0])).unwrap(),
                    Consistency::Any);
-        assert_eq!(Consistency::from_cursor(&mut Cursor::new(&[0, 1])),
+        assert_eq!(Consistency::from_cursor(&mut Cursor::new(&[0, 1])).unwrap(),
                    Consistency::One);
-        assert_eq!(Consistency::from_cursor(&mut Cursor::new(&[0, 2])),
+        assert_eq!(Consistency::from_cursor(&mut Cursor::new(&[0, 2])).unwrap(),
                    Consistency::Two);
-        assert_eq!(Consistency::from_cursor(&mut Cursor::new(&[0, 3])),
+        assert_eq!(Consistency::from_cursor(&mut Cursor::new(&[0, 3])).unwrap(),
                    Consistency::Three);
-        assert_eq!(Consistency::from_cursor(&mut Cursor::new(&[0, 4])),
+        assert_eq!(Consistency::from_cursor(&mut Cursor::new(&[0, 4])).unwrap(),
                    Consistency::Quorum);
-        assert_eq!(Consistency::from_cursor(&mut Cursor::new(&[0, 5])),
+        assert_eq!(Consistency::from_cursor(&mut Cursor::new(&[0, 5])).unwrap(),
                    Consistency::All);
-        assert_eq!(Consistency::from_cursor(&mut Cursor::new(&[0, 6])),
+        assert_eq!(Consistency::from_cursor(&mut Cursor::new(&[0, 6])).unwrap(),
                    Consistency::LocalQuorum);
-        assert_eq!(Consistency::from_cursor(&mut Cursor::new(&[0, 7])),
+        assert_eq!(Consistency::from_cursor(&mut Cursor::new(&[0, 7])).unwrap(),
                    Consistency::EachQuorum);
-        assert_eq!(Consistency::from_cursor(&mut Cursor::new(&[0, 8])),
+        assert_eq!(Consistency::from_cursor(&mut Cursor::new(&[0, 8])).unwrap(),
                    Consistency::Serial);
-        assert_eq!(Consistency::from_cursor(&mut Cursor::new(&[0, 9])),
+        assert_eq!(Consistency::from_cursor(&mut Cursor::new(&[0, 9])).unwrap(),
                    Consistency::LocalSerial);
-        assert_eq!(Consistency::from_cursor(&mut Cursor::new(&[0, 10])),
+        assert_eq!(Consistency::from_cursor(&mut Cursor::new(&[0, 10])).unwrap(),
                    Consistency::LocalOne);
     }
 
diff --git a/src/events.rs b/src/events.rs
index 8a58c4b..5420db0 100644
--- a/src/events.rs
+++ b/src/events.rs
@@ -51,10 +51,11 @@ impl<X: CDRSTransport> Listener<X> {
     pub fn start(&mut self, compressor: &Compression) -> error::Result<()> {
         loop {
             let event_opt = try!(parse_frame(&mut self.transport, compressor))
-                .get_body()
+                .get_body()?
                 .into_server_event();
 
             let event = if event_opt.is_some() {
+                // unwrap is safe is we've checked that event_opt.is_some()
                 event_opt.unwrap().event as ServerEvent
             } else {
                 continue;
diff --git a/src/frame/events.rs b/src/frame/events.rs
index 987f351..2d3d5e5 100644
--- a/src/frame/events.rs
+++ b/src/frame/events.rs
@@ -2,6 +2,7 @@ use std::io::Cursor;
 use std::cmp::PartialEq;
 
 use FromCursor;
+use error;
 use types::{CString, CStringList, CInet};
 
 // Event types
@@ -94,16 +95,17 @@ impl PartialEq<SimpleServerEvent> for ServerEvent {
 }
 
 impl FromCursor for ServerEvent {
-    fn from_cursor(mut cursor: &mut Cursor<&[u8]>) -> ServerEvent {
-        let event_type = CString::from_cursor(&mut cursor);
-        match event_type.as_str() {
-            TOPOLOGY_CHANGE => {
-                ServerEvent::TopologyChange(TopologyChange::from_cursor(&mut cursor))
-            }
-            STATUS_CHANGE => ServerEvent::StatusChange(StatusChange::from_cursor(&mut cursor)),
-            SCHEMA_CHANGE => ServerEvent::SchemaChange(SchemaChange::from_cursor(&mut cursor)),
-            _ => unreachable!(),
-        }
+    fn from_cursor(mut cursor: &mut Cursor<&[u8]>) -> error::Result<ServerEvent> {
+        let event_type = CString::from_cursor(&mut cursor)?;
+        Ok(match event_type.as_str() {
+               TOPOLOGY_CHANGE => {
+                   ServerEvent::TopologyChange(TopologyChange::from_cursor(&mut cursor)?)
+               }
+               STATUS_CHANGE => ServerEvent::StatusChange(StatusChange::from_cursor(&mut cursor)?),
+               SCHEMA_CHANGE => ServerEvent::SchemaChange(SchemaChange::from_cursor(&mut cursor)?),
+               // TODO: return error
+               _ => unreachable!(),
+           })
     }
 }
 
@@ -115,14 +117,14 @@ pub struct TopologyChange {
 }
 
 impl FromCursor for TopologyChange {
-    fn from_cursor(mut cursor: &mut Cursor<&[u8]>) -> TopologyChange {
-        let change_type = TopologyChangeType::from_cursor(&mut cursor);
-        let addr = CInet::from_cursor(&mut cursor);
-
-        TopologyChange {
-            change_type: change_type,
-            addr: addr,
-        }
+    fn from_cursor(mut cursor: &mut Cursor<&[u8]>) -> error::Result<TopologyChange> {
+        let change_type = TopologyChangeType::from_cursor(&mut cursor)?;
+        let addr = CInet::from_cursor(&mut cursor)?;
+
+        Ok(TopologyChange {
+               change_type: change_type,
+               addr: addr,
+           })
     }
 }
 
@@ -133,12 +135,13 @@ pub enum TopologyChangeType {
 }
 
 impl FromCursor for TopologyChangeType {
-    fn from_cursor(mut cursor: &mut Cursor<&[u8]>) -> TopologyChangeType {
-        match CString::from_cursor(&mut cursor).as_str() {
-            NEW_NODE => TopologyChangeType::NewNode,
-            REMOVED_NODE => TopologyChangeType::RemovedNode,
-            _ => unreachable!(),
-        }
+    fn from_cursor(mut cursor: &mut Cursor<&[u8]>) -> error::Result<TopologyChangeType> {
+        CString::from_cursor(&mut cursor).map(|tc| match tc.as_str() {
+                                                  NEW_NODE => TopologyChangeType::NewNode,
+                                                  REMOVED_NODE => TopologyChangeType::RemovedNode,
+                                                  // TODO: return error
+                                                  _ => unreachable!(),
+                                              })
     }
 }
 
@@ -150,14 +153,14 @@ pub struct StatusChange {
 }
 
 impl FromCursor for StatusChange {
-    fn from_cursor(mut cursor: &mut Cursor<&[u8]>) -> StatusChange {
-        let change_type = StatusChangeType::from_cursor(&mut cursor);
-        let addr = CInet::from_cursor(&mut cursor);
-
-        StatusChange {
-            change_type: change_type,
-            addr: addr,
-        }
+    fn from_cursor(mut cursor: &mut Cursor<&[u8]>) -> error::Result<StatusChange> {
+        let change_type = StatusChangeType::from_cursor(&mut cursor)?;
+        let addr = CInet::from_cursor(&mut cursor)?;
+
+        Ok(StatusChange {
+               change_type: change_type,
+               addr: addr,
+           })
     }
 }
 
@@ -168,12 +171,13 @@ pub enum StatusChangeType {
 }
 
 impl FromCursor for StatusChangeType {
-    fn from_cursor(mut cursor: &mut Cursor<&[u8]>) -> StatusChangeType {
-        match CString::from_cursor(&mut cursor).as_str() {
-            UP => StatusChangeType::Up,
-            DOWN => StatusChangeType::Down,
-            _ => unreachable!(),
-        }
+    fn from_cursor(mut cursor: &mut Cursor<&[u8]>) -> error::Result<StatusChangeType> {
+        CString::from_cursor(&mut cursor).map(|sct| match sct.as_str() {
+                                                  UP => StatusChangeType::Up,
+                                                  DOWN => StatusChangeType::Down,
+                                                  // TODO: return error
+                                                  _ => unreachable!(),
+                                              })
     }
 }
 
@@ -186,16 +190,16 @@ pub struct SchemaChange {
 }
 
 impl FromCursor for SchemaChange {
-    fn from_cursor(mut cursor: &mut Cursor<&[u8]>) -> SchemaChange {
-        let change_type = ChangeType::from_cursor(&mut cursor);
-        let target = Target::from_cursor(&mut cursor);
-        let options = ChangeSchemeOptions::from_cursor_and_target(&mut cursor, &target);
-
-        SchemaChange {
-            change_type: change_type,
-            target: target,
-            options: options,
-        }
+    fn from_cursor(mut cursor: &mut Cursor<&[u8]>) -> error::Result<SchemaChange> {
+        let change_type = ChangeType::from_cursor(&mut cursor)?;
+        let target = Target::from_cursor(&mut cursor)?;
+        let options = ChangeSchemeOptions::from_cursor_and_target(&mut cursor, &target)?;
+
+        Ok(SchemaChange {
+               change_type: change_type,
+               target: target,
+               options: options,
+           })
     }
 }
 
@@ -208,13 +212,14 @@ pub enum ChangeType {
 }
 
 impl FromCursor for ChangeType {
-    fn from_cursor(mut cursor: &mut Cursor<&[u8]>) -> ChangeType {
-        match CString::from_cursor(&mut cursor).as_str() {
-            CREATED => ChangeType::Created,
-            UPDATED => ChangeType::Updated,
-            DROPPED => ChangeType::Dropped,
-            _ => unreachable!(),
-        }
+    fn from_cursor(mut cursor: &mut Cursor<&[u8]>) -> error::Result<ChangeType> {
+        CString::from_cursor(&mut cursor).map(|ct| match ct.as_str() {
+                                                  CREATED => ChangeType::Created,
+                                                  UPDATED => ChangeType::Updated,
+                                                  DROPPED => ChangeType::Dropped,
+                                                  // TODO: return error
+                                                  _ => unreachable!(),
+                                              })
     }
 }
 
@@ -229,15 +234,16 @@ pub enum Target {
 }
 
 impl FromCursor for Target {
-    fn from_cursor(mut cursor: &mut Cursor<&[u8]>) -> Target {
-        match CString::from_cursor(&mut cursor).as_str() {
-            KEYSPACE => Target::Keyspace,
-            TABLE => Target::Table,
-            TYPE => Target::Type,
-            FUNCTION => Target::Function,
-            AGGREGATE => Target::Aggregate,
-            _ => unreachable!(),
-        }
+    fn from_cursor(mut cursor: &mut Cursor<&[u8]>) -> error::Result<Target> {
+        CString::from_cursor(&mut cursor).map(|t| match t.as_str() {
+                                                  KEYSPACE => Target::Keyspace,
+                                                  TABLE => Target::Table,
+                                                  TYPE => Target::Type,
+                                                  FUNCTION => Target::Function,
+                                                  AGGREGATE => Target::Aggregate,
+                                                  // TODO: return error
+                                                  _ => unreachable!(),
+                                              })
     }
 }
 
@@ -258,32 +264,36 @@ pub enum ChangeSchemeOptions {
 impl ChangeSchemeOptions {
     fn from_cursor_and_target(mut cursor: &mut Cursor<&[u8]>,
                               target: &Target)
-                              -> ChangeSchemeOptions {
-        match target {
-            &Target::Keyspace => ChangeSchemeOptions::from_cursor_keyspace(&mut cursor),
-            &Target::Table | &Target::Type => {
-                ChangeSchemeOptions::from_cursor_table_type(&mut cursor)
-            }
-            &Target::Function |
-            &Target::Aggregate => ChangeSchemeOptions::from_cursor_function_aggregate(&mut cursor),
-        }
+                              -> error::Result<ChangeSchemeOptions> {
+        Ok(match target {
+               &Target::Keyspace => ChangeSchemeOptions::from_cursor_keyspace(&mut cursor)?,
+               &Target::Table | &Target::Type => {
+                   ChangeSchemeOptions::from_cursor_table_type(&mut cursor)?
+               }
+               &Target::Function |
+               &Target::Aggregate => {
+                   ChangeSchemeOptions::from_cursor_function_aggregate(&mut cursor)?
+               }
+           })
     }
 
-    fn from_cursor_keyspace(mut cursor: &mut Cursor<&[u8]>) -> ChangeSchemeOptions {
-        ChangeSchemeOptions::Keyspace(CString::from_cursor(&mut cursor).into_plain())
+    fn from_cursor_keyspace(mut cursor: &mut Cursor<&[u8]>) -> error::Result<ChangeSchemeOptions> {
+        Ok(ChangeSchemeOptions::Keyspace(CString::from_cursor(&mut cursor)?.into_plain()))
     }
 
-    fn from_cursor_table_type(mut cursor: &mut Cursor<&[u8]>) -> ChangeSchemeOptions {
-        let keyspace = CString::from_cursor(&mut cursor).into_plain();
-        let name = CString::from_cursor(&mut cursor).into_plain();
-        ChangeSchemeOptions::TableType((keyspace, name))
+    fn from_cursor_table_type(mut cursor: &mut Cursor<&[u8]>)
+                              -> error::Result<ChangeSchemeOptions> {
+        let keyspace = CString::from_cursor(&mut cursor)?.into_plain();
+        let name = CString::from_cursor(&mut cursor)?.into_plain();
+        Ok(ChangeSchemeOptions::TableType((keyspace, name)))
     }
 
-    fn from_cursor_function_aggregate(mut cursor: &mut Cursor<&[u8]>) -> ChangeSchemeOptions {
-        let keyspace = CString::from_cursor(&mut cursor).into_plain();
-        let name = CString::from_cursor(&mut cursor).into_plain();
-        let types = CStringList::from_cursor(&mut cursor).into_plain();
-        ChangeSchemeOptions::FunctionAggregate((keyspace, name, types))
+    fn from_cursor_function_aggregate(mut cursor: &mut Cursor<&[u8]>)
+                                      -> error::Result<ChangeSchemeOptions> {
+        let keyspace = CString::from_cursor(&mut cursor)?.into_plain();
+        let name = CString::from_cursor(&mut cursor)?.into_plain();
+        let types = CStringList::from_cursor(&mut cursor)?.into_plain();
+        Ok(ChangeSchemeOptions::FunctionAggregate((keyspace, name, types)))
     }
 }
 
@@ -312,12 +322,12 @@ mod topology_change_type_test {
     fn from_cursor() {
         let a = &[0, 8, 78, 69, 87, 95, 78, 79, 68, 69];
         let mut new_node: Cursor<&[u8]> = Cursor::new(a);
-        assert_eq!(TopologyChangeType::from_cursor(&mut new_node),
+        assert_eq!(TopologyChangeType::from_cursor(&mut new_node).unwrap(),
                    TopologyChangeType::NewNode);
 
         let b = &[0, 12, 82, 69, 77, 79, 86, 69, 68, 95, 78, 79, 68, 69];
         let mut removed_node: Cursor<&[u8]> = Cursor::new(b);
-        assert_eq!(TopologyChangeType::from_cursor(&mut removed_node),
+        assert_eq!(TopologyChangeType::from_cursor(&mut removed_node).unwrap(),
                    TopologyChangeType::RemovedNode);
     }
 
@@ -326,7 +336,7 @@ mod topology_change_type_test {
     fn from_cursor_wrong() {
         let a = &[0, 1, 78];
         let mut wrong: Cursor<&[u8]> = Cursor::new(a);
-        let _ = TopologyChangeType::from_cursor(&mut wrong);
+        let _ = TopologyChangeType::from_cursor(&mut wrong).unwrap();
     }
 }
 
@@ -340,11 +350,12 @@ mod status_change_type_test {
     fn from_cursor() {
         let a = &[0, 2, 85, 80];
         let mut up: Cursor<&[u8]> = Cursor::new(a);
-        assert_eq!(StatusChangeType::from_cursor(&mut up), StatusChangeType::Up);
+        assert_eq!(StatusChangeType::from_cursor(&mut up).unwrap(),
+                   StatusChangeType::Up);
 
         let b = &[0, 4, 68, 79, 87, 78];
         let mut down: Cursor<&[u8]> = Cursor::new(b);
-        assert_eq!(StatusChangeType::from_cursor(&mut down),
+        assert_eq!(StatusChangeType::from_cursor(&mut down).unwrap(),
                    StatusChangeType::Down);
     }
 
@@ -353,7 +364,7 @@ mod status_change_type_test {
     fn from_cursor_wrong() {
         let a = &[0, 1, 78];
         let mut wrong: Cursor<&[u8]> = Cursor::new(a);
-        let _ = StatusChangeType::from_cursor(&mut wrong);
+        let _ = StatusChangeType::from_cursor(&mut wrong).unwrap();
     }
 }
 
@@ -367,15 +378,18 @@ mod schema_change_type_test {
     fn from_cursor() {
         let a = &[0, 7, 67, 82, 69, 65, 84, 69, 68];
         let mut created: Cursor<&[u8]> = Cursor::new(a);
-        assert_eq!(ChangeType::from_cursor(&mut created), ChangeType::Created);
+        assert_eq!(ChangeType::from_cursor(&mut created).unwrap(),
+                   ChangeType::Created);
 
         let b = &[0, 7, 85, 80, 68, 65, 84, 69, 68];
         let mut updated: Cursor<&[u8]> = Cursor::new(b);
-        assert_eq!(ChangeType::from_cursor(&mut updated), ChangeType::Updated);
+        assert_eq!(ChangeType::from_cursor(&mut updated).unwrap(),
+                   ChangeType::Updated);
 
         let c = &[0, 7, 68, 82, 79, 80, 80, 69, 68];
         let mut dropped: Cursor<&[u8]> = Cursor::new(c);
-        assert_eq!(ChangeType::from_cursor(&mut dropped), ChangeType::Dropped);
+        assert_eq!(ChangeType::from_cursor(&mut dropped).unwrap(),
+                   ChangeType::Dropped);
     }
 
     #[test]
@@ -383,7 +397,7 @@ mod schema_change_type_test {
     fn from_cursor_wrong() {
         let a = &[0, 1, 78];
         let mut wrong: Cursor<&[u8]> = Cursor::new(a);
-        let _ = ChangeType::from_cursor(&mut wrong);
+        let _ = ChangeType::from_cursor(&mut wrong).unwrap();
     }
 }
 
@@ -397,23 +411,26 @@ mod schema_change_target_test {
     fn from_cursor() {
         let a = &[0, 8, 75, 69, 89, 83, 80, 65, 67, 69];
         let mut keyspace: Cursor<&[u8]> = Cursor::new(a);
-        assert_eq!(Target::from_cursor(&mut keyspace), Target::Keyspace);
+        assert_eq!(Target::from_cursor(&mut keyspace).unwrap(),
+                   Target::Keyspace);
 
         let b = &[0, 5, 84, 65, 66, 76, 69];
         let mut table: Cursor<&[u8]> = Cursor::new(b);
-        assert_eq!(Target::from_cursor(&mut table), Target::Table);
+        assert_eq!(Target::from_cursor(&mut table).unwrap(), Target::Table);
 
         let c = &[0, 4, 84, 89, 80, 69];
         let mut _type: Cursor<&[u8]> = Cursor::new(c);
-        assert_eq!(Target::from_cursor(&mut _type), Target::Type);
+        assert_eq!(Target::from_cursor(&mut _type).unwrap(), Target::Type);
 
         let d = &[0, 8, 70, 85, 78, 67, 84, 73, 79, 78];
         let mut function: Cursor<&[u8]> = Cursor::new(d);
-        assert_eq!(Target::from_cursor(&mut function), Target::Function);
+        assert_eq!(Target::from_cursor(&mut function).unwrap(),
+                   Target::Function);
 
         let e = &[0, 9, 65, 71, 71, 82, 69, 71, 65, 84, 69];
         let mut aggregate: Cursor<&[u8]> = Cursor::new(e);
-        assert_eq!(Target::from_cursor(&mut aggregate), Target::Aggregate);
+        assert_eq!(Target::from_cursor(&mut aggregate).unwrap(),
+                   Target::Aggregate);
     }
 
     #[test]
@@ -421,7 +438,7 @@ mod schema_change_target_test {
     fn from_cursor_wrong() {
         let a = &[0, 1, 78];
         let mut wrong: Cursor<&[u8]> = Cursor::new(a);
-        let _ = Target::from_cursor(&mut wrong);
+        let _ = Target::from_cursor(&mut wrong).unwrap();
     }
 }
 
@@ -474,7 +491,7 @@ mod server_event {
                       0,
                       1];
         let mut c: Cursor<&[u8]> = Cursor::new(bytes);
-        let event = ServerEvent::from_cursor(&mut c);
+        let event = ServerEvent::from_cursor(&mut c).unwrap();
         match event {
             ServerEvent::TopologyChange(ref tc) => {
                 assert_eq!(tc.change_type, TopologyChangeType::NewNode);
@@ -531,7 +548,7 @@ mod server_event {
                       0,
                       1];
         let mut c: Cursor<&[u8]> = Cursor::new(bytes);
-        let event = ServerEvent::from_cursor(&mut c);
+        let event = ServerEvent::from_cursor(&mut c).unwrap();
         match event {
             ServerEvent::TopologyChange(ref tc) => {
                 assert_eq!(tc.change_type, TopologyChangeType::RemovedNode);
@@ -576,7 +593,7 @@ mod server_event {
                       0,
                       1];
         let mut c: Cursor<&[u8]> = Cursor::new(bytes);
-        let event = ServerEvent::from_cursor(&mut c);
+        let event = ServerEvent::from_cursor(&mut c).unwrap();
         match event {
             ServerEvent::StatusChange(ref tc) => {
                 assert_eq!(tc.change_type, StatusChangeType::Up);
@@ -623,7 +640,7 @@ mod server_event {
                       0,
                       1];
         let mut c: Cursor<&[u8]> = Cursor::new(bytes);
-        let event = ServerEvent::from_cursor(&mut c);
+        let event = ServerEvent::from_cursor(&mut c).unwrap();
         match event {
             ServerEvent::StatusChange(ref tc) => {
                 assert_eq!(tc.change_type, StatusChangeType::Down);
@@ -682,7 +699,7 @@ mod server_event {
                          107,
                          115];
         let mut ks: Cursor<&[u8]> = Cursor::new(keyspace);
-        let ks_event = ServerEvent::from_cursor(&mut ks);
+        let ks_event = ServerEvent::from_cursor(&mut ks).unwrap();
         match ks_event {
             ServerEvent::SchemaChange(ref _c) => {
                 assert_eq!(_c.change_type, ChangeType::Created);
@@ -749,7 +766,7 @@ mod server_event {
                       108,
                       101];
         let mut tb: Cursor<&[u8]> = Cursor::new(table);
-        let tb_event = ServerEvent::from_cursor(&mut tb);
+        let tb_event = ServerEvent::from_cursor(&mut tb).unwrap();
         match tb_event {
             ServerEvent::SchemaChange(ref _c) => {
                 assert_eq!(_c.change_type, ChangeType::Created);
@@ -817,7 +834,7 @@ mod server_event {
                       108,
                       101];
         let mut tp: Cursor<&[u8]> = Cursor::new(_type);
-        let tp_event = ServerEvent::from_cursor(&mut tp);
+        let tp_event = ServerEvent::from_cursor(&mut tp).unwrap();
         match tp_event {
             ServerEvent::SchemaChange(ref _c) => {
                 assert_eq!(_c.change_type, ChangeType::Created);
@@ -888,7 +905,7 @@ mod server_event {
                          0,
                          0];
         let mut fnct: Cursor<&[u8]> = Cursor::new(function);
-        let fnct_event = ServerEvent::from_cursor(&mut fnct);
+        let fnct_event = ServerEvent::from_cursor(&mut fnct).unwrap();
         match fnct_event {
             ServerEvent::SchemaChange(ref _c) => {
                 assert_eq!(_c.change_type, ChangeType::Created);
@@ -960,7 +977,7 @@ mod server_event {
                           0,
                           0];
         let mut aggr: Cursor<&[u8]> = Cursor::new(aggregate);
-        let aggr_event = ServerEvent::from_cursor(&mut aggr);
+        let aggr_event = ServerEvent::from_cursor(&mut aggr).unwrap();
         match aggr_event {
             ServerEvent::SchemaChange(ref _c) => {
                 assert_eq!(_c.change_type, ChangeType::Created);
@@ -1025,7 +1042,7 @@ mod server_event {
                          107,
                          115];
         let mut ks: Cursor<&[u8]> = Cursor::new(keyspace);
-        let ks_event = ServerEvent::from_cursor(&mut ks);
+        let ks_event = ServerEvent::from_cursor(&mut ks).unwrap();
         match ks_event {
             ServerEvent::SchemaChange(ref _c) => {
                 assert_eq!(_c.change_type, ChangeType::Updated);
@@ -1092,7 +1109,7 @@ mod server_event {
                       108,
                       101];
         let mut tb: Cursor<&[u8]> = Cursor::new(table);
-        let tb_event = ServerEvent::from_cursor(&mut tb);
+        let tb_event = ServerEvent::from_cursor(&mut tb).unwrap();
         match tb_event {
             ServerEvent::SchemaChange(ref _c) => {
                 assert_eq!(_c.change_type, ChangeType::Updated);
@@ -1160,7 +1177,7 @@ mod server_event {
                       108,
                       101];
         let mut tp: Cursor<&[u8]> = Cursor::new(_type);
-        let tp_event = ServerEvent::from_cursor(&mut tp);
+        let tp_event = ServerEvent::from_cursor(&mut tp).unwrap();
         match tp_event {
             ServerEvent::SchemaChange(ref _c) => {
                 assert_eq!(_c.change_type, ChangeType::Updated);
@@ -1231,7 +1248,7 @@ mod server_event {
                          0,
                          0];
         let mut fnct: Cursor<&[u8]> = Cursor::new(function);
-        let fnct_event = ServerEvent::from_cursor(&mut fnct);
+        let fnct_event = ServerEvent::from_cursor(&mut fnct).unwrap();
         match fnct_event {
             ServerEvent::SchemaChange(ref _c) => {
                 assert_eq!(_c.change_type, ChangeType::Updated);
@@ -1303,7 +1320,7 @@ mod server_event {
                           0,
                           0];
         let mut aggr: Cursor<&[u8]> = Cursor::new(aggregate);
-        let aggr_event = ServerEvent::from_cursor(&mut aggr);
+        let aggr_event = ServerEvent::from_cursor(&mut aggr).unwrap();
         match aggr_event {
             ServerEvent::SchemaChange(ref _c) => {
                 assert_eq!(_c.change_type, ChangeType::Updated);
@@ -1368,7 +1385,7 @@ mod server_event {
                          107,
                          115];
         let mut ks: Cursor<&[u8]> = Cursor::new(keyspace);
-        let ks_event = ServerEvent::from_cursor(&mut ks);
+        let ks_event = ServerEvent::from_cursor(&mut ks).unwrap();
         match ks_event {
             ServerEvent::SchemaChange(ref _c) => {
                 assert_eq!(_c.change_type, ChangeType::Dropped);
@@ -1435,7 +1452,7 @@ mod server_event {
                       108,
                       101];
         let mut tb: Cursor<&[u8]> = Cursor::new(table);
-        let tb_event = ServerEvent::from_cursor(&mut tb);
+        let tb_event = ServerEvent::from_cursor(&mut tb).unwrap();
         match tb_event {
             ServerEvent::SchemaChange(ref _c) => {
                 assert_eq!(_c.change_type, ChangeType::Dropped);
@@ -1503,7 +1520,7 @@ mod server_event {
                       108,
                       101];
         let mut tp: Cursor<&[u8]> = Cursor::new(_type);
-        let tp_event = ServerEvent::from_cursor(&mut tp);
+        let tp_event = ServerEvent::from_cursor(&mut tp).unwrap();
         match tp_event {
             ServerEvent::SchemaChange(ref _c) => {
                 assert_eq!(_c.change_type, ChangeType::Dropped);
@@ -1574,7 +1591,7 @@ mod server_event {
                          0,
                          0];
         let mut fnct: Cursor<&[u8]> = Cursor::new(function);
-        let fnct_event = ServerEvent::from_cursor(&mut fnct);
+        let fnct_event = ServerEvent::from_cursor(&mut fnct).unwrap();
         match fnct_event {
             ServerEvent::SchemaChange(ref _c) => {
                 assert_eq!(_c.change_type, ChangeType::Dropped);
@@ -1646,7 +1663,7 @@ mod server_event {
                           0,
                           0];
         let mut aggr: Cursor<&[u8]> = Cursor::new(aggregate);
-        let aggr_event = ServerEvent::from_cursor(&mut aggr);
+        let aggr_event = ServerEvent::from_cursor(&mut aggr).unwrap();
         match aggr_event {
             ServerEvent::SchemaChange(ref _c) => {
                 assert_eq!(_c.change_type, ChangeType::Dropped);
diff --git a/src/frame/frame_auth_challenge.rs b/src/frame/frame_auth_challenge.rs
index 6fc5065..7e0d527 100644
--- a/src/frame/frame_auth_challenge.rs
+++ b/src/frame/frame_auth_challenge.rs
@@ -1,5 +1,7 @@
 use std::io::Cursor;
+
 use FromCursor;
+use error;
 use types::CBytes;
 
 /// Server authentication challenge.
@@ -9,8 +11,8 @@ pub struct BodyResAuthChallenge {
 }
 
 impl FromCursor for BodyResAuthChallenge {
-    fn from_cursor(mut cursor: &mut Cursor<&[u8]>) -> BodyResAuthChallenge {
-        BodyResAuthChallenge { data: CBytes::from_cursor(&mut cursor) }
+    fn from_cursor(mut cursor: &mut Cursor<&[u8]>) -> error::Result<BodyResAuthChallenge> {
+        CBytes::from_cursor(&mut cursor).map(|data| BodyResAuthChallenge { data: data })
     }
 }
 
@@ -24,7 +26,7 @@ mod tests {
     fn body_res_auth_challenge_from_cursor() {
         let few_bytes = &[0, 0, 0, 10, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
         let mut cursor: Cursor<&[u8]> = Cursor::new(few_bytes);
-        let body = BodyResAuthChallenge::from_cursor(&mut cursor);
+        let body = BodyResAuthChallenge::from_cursor(&mut cursor).unwrap();
         assert_eq!(body.data.into_plain(), vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
     }
 }
diff --git a/src/frame/frame_auth_success.rs b/src/frame/frame_auth_success.rs
index 8187ad5..f0bd833 100644
--- a/src/frame/frame_auth_success.rs
+++ b/src/frame/frame_auth_success.rs
@@ -1,13 +1,15 @@
-use FromCursor;
 use std::io::Cursor;
 
+use FromCursor;
+use error;
+
 /// `BodyReqAuthSuccess` is a frame that represents a successfull authentication response.
 #[derive(Debug, PartialEq)]
 pub struct BodyReqAuthSuccess {}
 
 impl FromCursor for BodyReqAuthSuccess {
-    fn from_cursor(mut _cursor: &mut Cursor<&[u8]>) -> BodyReqAuthSuccess {
-        BodyReqAuthSuccess {}
+    fn from_cursor(mut _cursor: &mut Cursor<&[u8]>) -> error::Result<BodyReqAuthSuccess> {
+        Ok(BodyReqAuthSuccess {})
     }
 }
 
@@ -21,7 +23,7 @@ mod tests {
     fn test_name() {
         let rnd_bytes = [4, 5, 3, 8, 4, 6, 5, 0, 3, 7, 2];
         let mut cursor: Cursor<&[u8]> = Cursor::new(&rnd_bytes);
-        let body = BodyReqAuthSuccess::from_cursor(&mut cursor);
+        let body = BodyReqAuthSuccess::from_cursor(&mut cursor).unwrap();
         assert_eq!(body, BodyReqAuthSuccess {});
     }
 }
diff --git a/src/frame/frame_authenticate.rs b/src/frame/frame_authenticate.rs
index 35332d6..08a266b 100644
--- a/src/frame/frame_authenticate.rs
+++ b/src/frame/frame_authenticate.rs
@@ -1,5 +1,7 @@
 use std::io::Cursor;
+
 use FromCursor;
+use error;
 use types::CString;
 
 /// A server authentication challenge.
@@ -9,8 +11,8 @@ pub struct BodyResAuthenticate {
 }
 
 impl FromCursor for BodyResAuthenticate {
-    fn from_cursor(mut cursor: &mut Cursor<&[u8]>) -> BodyResAuthenticate {
-        BodyResAuthenticate { data: CString::from_cursor(&mut cursor) }
+    fn from_cursor(mut cursor: &mut Cursor<&[u8]>) -> error::Result<BodyResAuthenticate> {
+        Ok(BodyResAuthenticate { data: CString::from_cursor(&mut cursor)? })
     }
 }
 
@@ -25,7 +27,7 @@ mod tests {
         // string "abcde"
         let data = [0, 5, 97, 98, 99, 100, 101];
         let mut cursor: Cursor<&[u8]> = Cursor::new(&data);
-        let body = BodyResAuthenticate::from_cursor(&mut cursor);
+        let body = BodyResAuthenticate::from_cursor(&mut cursor).unwrap();
         assert_eq!(body.data.as_str(), "abcde");
     }
 }
diff --git a/src/frame/frame_error.rs b/src/frame/frame_error.rs
index 543bae3..91fa5fe 100644
--- a/src/frame/frame_error.rs
+++ b/src/frame/frame_error.rs
@@ -4,6 +4,8 @@
 
 use std::io;
 use std::result;
+
+use error;
 use consistency::Consistency;
 use types::*;
 use FromCursor;
@@ -29,15 +31,16 @@ pub struct CDRSError {
 }
 
 impl FromCursor for CDRSError {
-    fn from_cursor(mut cursor: &mut io::Cursor<&[u8]>) -> CDRSError {
-        let error_code = CInt::from_cursor(&mut cursor);
-        let message = CString::from_cursor(&mut cursor);
-        let additional_info = AdditionalErrorInfo::from_cursor_with_code(&mut cursor, error_code);
-        CDRSError {
-            error_code: error_code,
-            message: message,
-            additional_info: additional_info,
-        }
+    fn from_cursor(mut cursor: &mut io::Cursor<&[u8]>) -> error::Result<CDRSError> {
+        let error_code = CInt::from_cursor(&mut cursor)?;
+        let message = CString::from_cursor(&mut cursor)?;
+        let additional_info = AdditionalErrorInfo::from_cursor_with_code(&mut cursor, error_code)?;
+
+        Ok(CDRSError {
+               error_code: error_code,
+               message: message,
+               additional_info: additional_info,
+           })
     }
 }
 
@@ -69,36 +72,50 @@ pub enum AdditionalErrorInfo {
 impl AdditionalErrorInfo {
     pub fn from_cursor_with_code(mut cursor: &mut io::Cursor<&[u8]>,
                                  error_code: CInt)
-                                 -> AdditionalErrorInfo {
-        match error_code {
-            0x0000 => AdditionalErrorInfo::Server(SimpleError::from_cursor(&mut cursor)),
-            0x000A => AdditionalErrorInfo::Protocol(SimpleError::from_cursor(&mut cursor)),
-            0x0100 => AdditionalErrorInfo::Authentication(SimpleError::from_cursor(&mut cursor)),
-            0x1000 => AdditionalErrorInfo::Unavailable(UnavailableError::from_cursor(&mut cursor)),
-            0x1001 => AdditionalErrorInfo::Overloaded(SimpleError::from_cursor(&mut cursor)),
-            0x1002 => AdditionalErrorInfo::IsBootstrapping(SimpleError::from_cursor(&mut cursor)),
-            0x1003 => AdditionalErrorInfo::Truncate(SimpleError::from_cursor(&mut cursor)),
-            0x1100 => {
-                AdditionalErrorInfo::WriteTimeout(WriteTimeoutError::from_cursor(&mut cursor))
-            }
-            0x1200 => AdditionalErrorInfo::ReadTimeout(ReadTimeoutError::from_cursor(&mut cursor)),
-            0x1300 => AdditionalErrorInfo::ReadFailure(ReadFailureError::from_cursor(&mut cursor)),
-            0x1400 => {
-                AdditionalErrorInfo::FunctionFailure(FunctionFailureError::from_cursor(&mut cursor))
-            }
-            0x1500 => {
-                AdditionalErrorInfo::WriteFailure(WriteFailureError::from_cursor(&mut cursor))
-            }
-            0x2000 => AdditionalErrorInfo::Syntax(SimpleError::from_cursor(&mut cursor)),
-            0x2100 => AdditionalErrorInfo::Unauthorized(SimpleError::from_cursor(&mut cursor)),
-            0x2200 => AdditionalErrorInfo::Invalid(SimpleError::from_cursor(&mut cursor)),
-            0x2300 => AdditionalErrorInfo::Config(SimpleError::from_cursor(&mut cursor)),
-            0x2400 => {
-                AdditionalErrorInfo::AlreadyExists(AlreadyExistsError::from_cursor(&mut cursor))
-            }
-            0x2500 => AdditionalErrorInfo::Unprepared(UnpreparedError::from_cursor(&mut cursor)),
-            _ => unreachable!(),
-        }
+                                 -> error::Result<AdditionalErrorInfo> {
+        Ok(match error_code {
+               0x0000 => AdditionalErrorInfo::Server(SimpleError::from_cursor(&mut cursor)?),
+               0x000A => AdditionalErrorInfo::Protocol(SimpleError::from_cursor(&mut cursor)?),
+               0x0100 => {
+                   AdditionalErrorInfo::Authentication(SimpleError::from_cursor(&mut cursor)?)
+               }
+               0x1000 => {
+                   AdditionalErrorInfo::Unavailable(UnavailableError::from_cursor(&mut cursor)?)
+               }
+               0x1001 => AdditionalErrorInfo::Overloaded(SimpleError::from_cursor(&mut cursor)?),
+               0x1002 => {
+                   AdditionalErrorInfo::IsBootstrapping(SimpleError::from_cursor(&mut cursor)?)
+               }
+               0x1003 => AdditionalErrorInfo::Truncate(SimpleError::from_cursor(&mut cursor)?),
+               0x1100 => {
+                   AdditionalErrorInfo::WriteTimeout(WriteTimeoutError::from_cursor(&mut cursor)?)
+               }
+               0x1200 => {
+                   AdditionalErrorInfo::ReadTimeout(ReadTimeoutError::from_cursor(&mut cursor)?)
+               }
+               0x1300 => {
+                   AdditionalErrorInfo::ReadFailure(ReadFailureError::from_cursor(&mut cursor)?)
+               }
+               0x1400 => {
+                   AdditionalErrorInfo::FunctionFailure(
+                       FunctionFailureError::from_cursor(&mut cursor)?)
+               }
+               0x1500 => {
+                   AdditionalErrorInfo::WriteFailure(WriteFailureError::from_cursor(&mut cursor)?)
+               }
+               0x2000 => AdditionalErrorInfo::Syntax(SimpleError::from_cursor(&mut cursor)?),
+               0x2100 => AdditionalErrorInfo::Unauthorized(SimpleError::from_cursor(&mut cursor)?),
+               0x2200 => AdditionalErrorInfo::Invalid(SimpleError::from_cursor(&mut cursor)?),
+               0x2300 => AdditionalErrorInfo::Config(SimpleError::from_cursor(&mut cursor)?),
+               0x2400 => {
+                   AdditionalErrorInfo::AlreadyExists(AlreadyExistsError::from_cursor(&mut cursor)?)
+               }
+               0x2500 => {
+                   AdditionalErrorInfo::Unprepared(UnpreparedError::from_cursor(&mut cursor)?)
+               }
+               // TODO: return error-like value
+               _ => unreachable!(),
+           })
     }
 }
 
@@ -107,8 +124,8 @@ impl AdditionalErrorInfo {
 pub struct SimpleError {}
 
 impl FromCursor for SimpleError {
-    fn from_cursor(mut _cursor: &mut io::Cursor<&[u8]>) -> SimpleError {
-        SimpleError {}
+    fn from_cursor(mut _cursor: &mut io::Cursor<&[u8]>) -> error::Result<SimpleError> {
+        Ok(SimpleError {})
     }
 }
 
@@ -126,16 +143,16 @@ pub struct UnavailableError {
 }
 
 impl FromCursor for UnavailableError {
-    fn from_cursor(mut cursor: &mut io::Cursor<&[u8]>) -> UnavailableError {
-        let cl = Consistency::from_cursor(&mut cursor);
-        let required = CInt::from_cursor(&mut cursor);
-        let alive = CInt::from_cursor(&mut cursor);
-
-        UnavailableError {
-            cl: cl,
-            required: required,
-            alive: alive,
-        }
+    fn from_cursor(mut cursor: &mut io::Cursor<&[u8]>) -> error::Result<UnavailableError> {
+        let cl = Consistency::from_cursor(&mut cursor)?;
+        let required = CInt::from_cursor(&mut cursor)?;
+        let alive = CInt::from_cursor(&mut cursor)?;
+
+        Ok(UnavailableError {
+               cl: cl,
+               required: required,
+               alive: alive,
+           })
     }
 }
 
@@ -153,18 +170,18 @@ pub struct WriteTimeoutError {
 }
 
 impl FromCursor for WriteTimeoutError {
-    fn from_cursor(mut cursor: &mut io::Cursor<&[u8]>) -> WriteTimeoutError {
-        let cl = Consistency::from_cursor(&mut cursor);
-        let received = CInt::from_cursor(&mut cursor);
-        let blockfor = CInt::from_cursor(&mut cursor);
-        let write_type = WriteType::from_cursor(&mut cursor);
-
-        WriteTimeoutError {
-            cl: cl,
-            received: received,
-            blockfor: blockfor,
-            write_type: write_type,
-        }
+    fn from_cursor(mut cursor: &mut io::Cursor<&[u8]>) -> error::Result<WriteTimeoutError> {
+        let cl = Consistency::from_cursor(&mut cursor)?;
+        let received = CInt::from_cursor(&mut cursor)?;
+        let blockfor = CInt::from_cursor(&mut cursor)?;
+        let write_type = WriteType::from_cursor(&mut cursor)?;
+
+        Ok(WriteTimeoutError {
+               cl: cl,
+               received: received,
+               blockfor: blockfor,
+               write_type: write_type,
+           })
     }
 }
 
@@ -188,17 +205,18 @@ impl ReadTimeoutError {
 }
 
 impl FromCursor for ReadTimeoutError {
-    fn from_cursor(mut cursor: &mut io::Cursor<&[u8]>) -> ReadTimeoutError {
-        let cl = Consistency::from_cursor(&mut cursor);
-        let received = CInt::from_cursor(&mut cursor);
-        let blockfor = CInt::from_cursor(&mut cursor);
-        let data_present = from_bytes(cursor_next_value(&mut cursor, 1).as_slice()) as u8;
-        ReadTimeoutError {
-            cl: cl,
-            received: received,
-            blockfor: blockfor,
-            data_present: data_present,
-        }
+    fn from_cursor(mut cursor: &mut io::Cursor<&[u8]>) -> error::Result<ReadTimeoutError> {
+        let cl = Consistency::from_cursor(&mut cursor)?;
+        let received = CInt::from_cursor(&mut cursor)?;
+        let blockfor = CInt::from_cursor(&mut cursor)?;
+        let data_present = try_from_bytes(cursor_next_value(&mut cursor, 1).as_slice())? as u8;
+
+        Ok(ReadTimeoutError {
+               cl: cl,
+               received: received,
+               blockfor: blockfor,
+               data_present: data_present,
+           })
     }
 }
 
@@ -224,19 +242,20 @@ impl ReadFailureError {
 }
 
 impl FromCursor for ReadFailureError {
-    fn from_cursor(mut cursor: &mut io::Cursor<&[u8]>) -> ReadFailureError {
-        let cl = Consistency::from_cursor(&mut cursor);
-        let received = CInt::from_cursor(&mut cursor);
-        let blockfor = CInt::from_cursor(&mut cursor);
-        let num_failures = CInt::from_cursor(&mut cursor);
-        let data_present = from_bytes(cursor_next_value(&mut cursor, 1).as_slice()) as u8;
-        ReadFailureError {
-            cl: cl,
-            received: received,
-            blockfor: blockfor,
-            num_failures: num_failures,
-            data_present: data_present,
-        }
+    fn from_cursor(mut cursor: &mut io::Cursor<&[u8]>) -> error::Result<ReadFailureError> {
+        let cl = Consistency::from_cursor(&mut cursor)?;
+        let received = CInt::from_cursor(&mut cursor)?;
+        let blockfor = CInt::from_cursor(&mut cursor)?;
+        let num_failures = CInt::from_cursor(&mut cursor)?;
+        let data_present = try_from_bytes(cursor_next_value(&mut cursor, 1).as_slice())? as u8;
+
+        Ok(ReadFailureError {
+               cl: cl,
+               received: received,
+               blockfor: blockfor,
+               num_failures: num_failures,
+               data_present: data_present,
+           })
     }
 }
 
@@ -252,15 +271,16 @@ pub struct FunctionFailureError {
 }
 
 impl FromCursor for FunctionFailureError {
-    fn from_cursor(mut cursor: &mut io::Cursor<&[u8]>) -> FunctionFailureError {
-        let keyspace = CString::from_cursor(&mut cursor);
-        let function = CString::from_cursor(&mut cursor);
-        let arg_types = CStringList::from_cursor(&mut cursor);
-        FunctionFailureError {
-            keyspace: keyspace,
-            function: function,
-            arg_types: arg_types,
-        }
+    fn from_cursor(mut cursor: &mut io::Cursor<&[u8]>) -> error::Result<FunctionFailureError> {
+        let keyspace = CString::from_cursor(&mut cursor)?;
+        let function = CString::from_cursor(&mut cursor)?;
+        let arg_types = CStringList::from_cursor(&mut cursor)?;
+
+        Ok(FunctionFailureError {
+               keyspace: keyspace,
+               function: function,
+               arg_types: arg_types,
+           })
     }
 }
 
@@ -281,19 +301,20 @@ pub struct WriteFailureError {
 }
 
 impl FromCursor for WriteFailureError {
-    fn from_cursor(mut cursor: &mut io::Cursor<&[u8]>) -> WriteFailureError {
-        let cl = Consistency::from_cursor(&mut cursor);
-        let received = CInt::from_cursor(&mut cursor);
-        let blockfor = CInt::from_cursor(&mut cursor);
-        let num_failures = CInt::from_cursor(&mut cursor);
-        let write_type = WriteType::from_cursor(&mut cursor);
-        WriteFailureError {
-            cl: cl,
-            received: received,
-            blockfor: blockfor,
-            num_failures: num_failures,
-            write_type: write_type,
-        }
+    fn from_cursor(mut cursor: &mut io::Cursor<&[u8]>) -> error::Result<WriteFailureError> {
+        let cl = Consistency::from_cursor(&mut cursor)?;
+        let received = CInt::from_cursor(&mut cursor)?;
+        let blockfor = CInt::from_cursor(&mut cursor)?;
+        let num_failures = CInt::from_cursor(&mut cursor)?;
+        let write_type = WriteType::from_cursor(&mut cursor)?;
+
+        Ok(WriteFailureError {
+               cl: cl,
+               received: received,
+               blockfor: blockfor,
+               num_failures: num_failures,
+               write_type: write_type,
+           })
     }
 }
 
@@ -317,15 +338,16 @@ pub enum WriteType {
 }
 
 impl FromCursor for WriteType {
-    fn from_cursor(mut cursor: &mut io::Cursor<&[u8]>) -> WriteType {
-        match CString::from_cursor(&mut cursor).as_str() {
-            "SIMPLE" => WriteType::Simple,
-            "BATCH" => WriteType::Batch,
-            "UNLOGGED_BATCH" => WriteType::UnloggedBatch,
-            "COUNTER" => WriteType::Counter,
-            "BATCH_LOG" => WriteType::BatchLog,
-            _ => unreachable!(),
-        }
+    fn from_cursor(mut cursor: &mut io::Cursor<&[u8]>) -> error::Result<WriteType> {
+        CString::from_cursor(&mut cursor).map(|wt| match wt.as_str() {
+                                                  "SIMPLE" => WriteType::Simple,
+                                                  "BATCH" => WriteType::Batch,
+                                                  "UNLOGGED_BATCH" => WriteType::UnloggedBatch,
+                                                  "COUNTER" => WriteType::Counter,
+                                                  "BATCH_LOG" => WriteType::BatchLog,
+                                                  // TODO: return error instead of panic
+                                                  _ => unreachable!(),
+                                              })
     }
 }
 
@@ -341,14 +363,14 @@ pub struct AlreadyExistsError {
 }
 
 impl FromCursor for AlreadyExistsError {
-    fn from_cursor(mut cursor: &mut io::Cursor<&[u8]>) -> AlreadyExistsError {
-        let ks = CString::from_cursor(&mut cursor);
-        let table = CString::from_cursor(&mut cursor);
-
-        AlreadyExistsError {
-            ks: ks,
-            table: table,
-        }
+    fn from_cursor(mut cursor: &mut io::Cursor<&[u8]>) -> error::Result<AlreadyExistsError> {
+        let ks = CString::from_cursor(&mut cursor)?;
+        let table = CString::from_cursor(&mut cursor)?;
+
+        Ok(AlreadyExistsError {
+               ks: ks,
+               table: table,
+           })
     }
 }
 
@@ -363,9 +385,9 @@ pub struct UnpreparedError {
 }
 
 impl FromCursor for UnpreparedError {
-    fn from_cursor(mut cursor: &mut io::Cursor<&[u8]>) -> UnpreparedError {
-        let id = CBytes::from_cursor(&mut cursor);
+    fn from_cursor(mut cursor: &mut io::Cursor<&[u8]>) -> error::Result<UnpreparedError> {
+        let id = CBytes::from_cursor(&mut cursor)?;
 
-        UnpreparedError { id: id }
+        Ok(UnpreparedError { id: id })
     }
 }
diff --git a/src/frame/frame_event.rs b/src/frame/frame_event.rs
index e6609c4..57d91d5 100644
--- a/src/frame/frame_event.rs
+++ b/src/frame/frame_event.rs
@@ -1,5 +1,7 @@
-use FromCursor;
 use std::io::Cursor;
+
+use FromCursor;
+use error;
 use frame::events::ServerEvent;
 
 #[derive(Debug)]
@@ -8,9 +10,10 @@ pub struct BodyResEvent {
 }
 
 impl FromCursor for BodyResEvent {
-    fn from_cursor(mut cursor: &mut Cursor<&[u8]>) -> BodyResEvent {
-        let event = ServerEvent::from_cursor(&mut cursor);
-        BodyResEvent { event: event }
+    fn from_cursor(mut cursor: &mut Cursor<&[u8]>) -> error::Result<BodyResEvent> {
+        let event = ServerEvent::from_cursor(&mut cursor)?;
+
+        Ok(BodyResEvent { event: event })
     }
 }
 
@@ -64,7 +67,7 @@ mod tests {
                      0,
                      1];
         let mut cursor: Cursor<&[u8]> = Cursor::new(&bytes);
-        let event = BodyResEvent::from_cursor(&mut cursor).event;
+        let event = BodyResEvent::from_cursor(&mut cursor).unwrap().event;
 
         match event {
             ServerEvent::TopologyChange(ref tc) => {
diff --git a/src/frame/frame_query.rs b/src/frame/frame_query.rs
index 2b55127..2bf4488 100644
--- a/src/frame/frame_query.rs
+++ b/src/frame/frame_query.rs
@@ -139,29 +139,37 @@ impl IntoBytes for ParamsReqQuery {
         v.push(self.flags_as_byte());
         if QueryFlags::has_value(self.flags_as_byte()) {
             // XXX clone
+            // XXX unwrap
             let values = self.values.clone().unwrap();
             v.extend_from_slice(to_short(values.len() as i16).as_slice());
             for val in values.iter() {
                 v.extend_from_slice(val.into_cbytes().as_slice());
             }
         }
-        if QueryFlags::has_with_paging_state(self.flags_as_byte()) {
+        if QueryFlags::has_with_paging_state(self.flags_as_byte()) && self.paging_state.is_some() {
             // XXX clone
             v.extend_from_slice(self.paging_state
                                     .clone()
+                                    // unwrap is safe as we've checked that
+                                    // self.paging_state.is_some()
                                     .unwrap()
                                     .into_cbytes()
                                     .as_slice());
         }
-        if QueryFlags::has_with_serial_consistency(self.flags_as_byte()) {
+        if QueryFlags::has_with_serial_consistency(self.flags_as_byte()) &&
+           self.serial_consistency.is_some() {
             // XXX clone
             v.extend_from_slice(self.serial_consistency
                                     .clone()
+                                    // unwrap is safe as we've checked that
+                                    // self.serial_consistency.is_some()
                                     .unwrap()
                                     .into_cbytes()
                                     .as_slice());
         }
-        if QueryFlags::has_with_default_timestamp(self.flags_as_byte()) {
+        if QueryFlags::has_with_default_timestamp(self.flags_as_byte()) &&
+           self.timestamp.is_some() {
+            // unwrap is safe as we've checked that self.timestamp.is_some()
             v.extend_from_slice(to_bigint(self.timestamp.unwrap()).as_slice());
         }
 
diff --git a/src/frame/frame_response.rs b/src/frame/frame_response.rs
index ecd468a..b69cc92 100644
--- a/src/frame/frame_response.rs
+++ b/src/frame/frame_response.rs
@@ -1,6 +1,7 @@
 use std::io::Cursor;
 
 use FromCursor;
+use error;
 use frame::Opcode;
 use frame::frame_result::{BodyResResultVoid, BodyResResultPrepared, BodyResResultRows,
                           BodyResResultSetKeyspace, ResResultBody};
@@ -33,37 +34,37 @@ pub enum ResponseBody {
 }
 
 impl ResponseBody {
-    pub fn from(bytes: &[u8], response_type: &Opcode) -> ResponseBody {
+    pub fn from(bytes: &[u8], response_type: &Opcode) -> error::Result<ResponseBody> {
         let mut cursor: Cursor<&[u8]> = Cursor::new(bytes);
-        match response_type {
-            // request frames
-            &Opcode::Startup => unreachable!(),
-            &Opcode::Options => unreachable!(),
-            &Opcode::Query => unreachable!(),
-            &Opcode::Prepare => unreachable!(),
-            &Opcode::Execute => unreachable!(),
-            &Opcode::Register => unreachable!(),
-            &Opcode::Batch => unreachable!(),
-            &Opcode::AuthResponse => unreachable!(),
+        Ok(match response_type {
+               // request frames
+               &Opcode::Startup => unreachable!(),
+               &Opcode::Options => unreachable!(),
+               &Opcode::Query => unreachable!(),
+               &Opcode::Prepare => unreachable!(),
+               &Opcode::Execute => unreachable!(),
+               &Opcode::Register => unreachable!(),
+               &Opcode::Batch => unreachable!(),
+               &Opcode::AuthResponse => unreachable!(),
 
-            // response frames
-            &Opcode::Error => ResponseBody::Error(CDRSError::from_cursor(&mut cursor)),
-            &Opcode::Ready => ResponseBody::Ready(BodyResResultVoid::from_cursor(&mut cursor)),
-            &Opcode::Authenticate => {
-                ResponseBody::Authenticate(BodyResAuthenticate::from_cursor(&mut cursor))
-            }
-            &Opcode::Supported => {
-                ResponseBody::Supported(BodyResSupported::from_cursor(&mut cursor))
-            }
-            &Opcode::Result => ResponseBody::Result(ResResultBody::from_cursor(&mut cursor)),
-            &Opcode::Event => ResponseBody::Event(BodyResEvent::from_cursor(&mut cursor)),
-            &Opcode::AuthChallenge => {
-                ResponseBody::AuthChallenge(BodyResAuthChallenge::from_cursor(&mut cursor))
-            }
-            &Opcode::AuthSuccess => {
-                ResponseBody::AuthSuccess(BodyReqAuthSuccess::from_cursor(&mut cursor))
-            }
-        }
+               // response frames
+               &Opcode::Error => ResponseBody::Error(CDRSError::from_cursor(&mut cursor)?),
+               &Opcode::Ready => ResponseBody::Ready(BodyResResultVoid::from_cursor(&mut cursor)?),
+               &Opcode::Authenticate => {
+                   ResponseBody::Authenticate(BodyResAuthenticate::from_cursor(&mut cursor)?)
+               }
+               &Opcode::Supported => {
+                   ResponseBody::Supported(BodyResSupported::from_cursor(&mut cursor)?)
+               }
+               &Opcode::Result => ResponseBody::Result(ResResultBody::from_cursor(&mut cursor)?),
+               &Opcode::Event => ResponseBody::Event(BodyResEvent::from_cursor(&mut cursor)?),
+               &Opcode::AuthChallenge => {
+                   ResponseBody::AuthChallenge(BodyResAuthChallenge::from_cursor(&mut cursor)?)
+               }
+               &Opcode::AuthSuccess => {
+                   ResponseBody::AuthSuccess(BodyReqAuthSuccess::from_cursor(&mut cursor)?)
+               }
+           })
     }
 
     pub fn into_rows(self) -> Option<Vec<Row>> {
diff --git a/src/frame/frame_result.rs b/src/frame/frame_result.rs
index 179d7ff..c5ce819 100644
--- a/src/frame/frame_result.rs
+++ b/src/frame/frame_result.rs
@@ -1,5 +1,7 @@
 use std::io::Cursor;
+
 use {IntoBytes, FromBytes, FromCursor};
+use error;
 use types::*;
 use types::rows::Row;
 use frame::events::SchemaChange;
@@ -33,20 +35,23 @@ impl IntoBytes for ResultKind {
 }
 
 impl FromBytes for ResultKind {
-    fn from_bytes(bytes: &[u8]) -> ResultKind {
-        match from_bytes(bytes) {
-            0x0001 => ResultKind::Void,
-            0x0002 => ResultKind::Rows,
-            0x0003 => ResultKind::SetKeyspace,
-            0x0004 => ResultKind::Prepared,
-            0x0005 => ResultKind::SchemaChange,
-            _ => unreachable!(),
-        }
+    fn from_bytes(bytes: &[u8]) -> error::Result<ResultKind> {
+        try_from_bytes(bytes)
+            .map_err(Into::into)
+            .map(|r| match r {
+                     0x0001 => ResultKind::Void,
+                     0x0002 => ResultKind::Rows,
+                     0x0003 => ResultKind::SetKeyspace,
+                     0x0004 => ResultKind::Prepared,
+                     0x0005 => ResultKind::SchemaChange,
+                     // TODO: return error
+                     _ => unreachable!(),
+                 })
     }
 }
 
 impl FromCursor for ResultKind {
-    fn from_cursor(mut cursor: &mut Cursor<&[u8]>) -> ResultKind {
+    fn from_cursor(mut cursor: &mut Cursor<&[u8]>) -> error::Result<ResultKind> {
         ResultKind::from_bytes(cursor_next_value(&mut cursor, INT_LEN as u64).as_slice())
     }
 }
@@ -73,21 +78,25 @@ impl ResResultBody {
     /// having knowledge about expected kind of result.
     fn parse_body_from_cursor(mut cursor: &mut Cursor<&[u8]>,
                               result_kind: ResultKind)
-                              -> ResResultBody {
-        match result_kind {
-            ResultKind::Void => ResResultBody::Void(BodyResResultVoid::from_cursor(&mut cursor)),
-            ResultKind::Rows => ResResultBody::Rows(BodyResResultRows::from_cursor(&mut cursor)),
-            ResultKind::SetKeyspace => {
-                ResResultBody::SetKeyspace(BodyResResultSetKeyspace::from_cursor(&mut cursor))
-            }
-            ResultKind::Prepared => {
-                ResResultBody::Prepared(BodyResResultPrepared::from_cursor(&mut cursor))
-            }
-            ResultKind::SchemaChange => {
-                ResResultBody::SchemaChange(SchemaChange::from_cursor(&mut cursor))
-            }
-
-        }
+                              -> error::Result<ResResultBody> {
+        Ok(match result_kind {
+               ResultKind::Void => {
+                   ResResultBody::Void(BodyResResultVoid::from_cursor(&mut cursor)?)
+               }
+               ResultKind::Rows => {
+                   ResResultBody::Rows(BodyResResultRows::from_cursor(&mut cursor)?)
+               }
+               ResultKind::SetKeyspace => {
+                   ResResultBody::SetKeyspace(BodyResResultSetKeyspace::from_cursor(&mut cursor)?)
+               }
+               ResultKind::Prepared => {
+                   ResResultBody::Prepared(BodyResResultPrepared::from_cursor(&mut cursor)?)
+               }
+               ResultKind::SchemaChange => {
+                   ResResultBody::SchemaChange(SchemaChange::from_cursor(&mut cursor)?)
+               }
+
+           })
     }
 
     /// It converts body into `Vec<Row>` if body's type is `Row` and returns `None` otherwise.
@@ -118,8 +127,9 @@ impl ResResultBody {
 }
 
 impl FromCursor for ResResultBody {
-    fn from_cursor(mut cursor: &mut Cursor<&[u8]>) -> ResResultBody {
-        let result_kind = ResultKind::from_cursor(&mut cursor);
+    fn from_cursor(mut cursor: &mut Cursor<&[u8]>) -> error::Result<ResResultBody> {
+        let result_kind = ResultKind::from_cursor(&mut cursor)?;
+
         ResResultBody::parse_body_from_cursor(&mut cursor, result_kind)
     }
 }
@@ -136,15 +146,15 @@ impl BodyResResultVoid {
 }
 
 impl FromBytes for BodyResResultVoid {
-    fn from_bytes(_bytes: &[u8]) -> BodyResResultVoid {
+    fn from_bytes(_bytes: &[u8]) -> error::Result<BodyResResultVoid> {
         // as it's empty by definition just create BodyResVoid
-        BodyResResultVoid::new()
+        Ok(BodyResResultVoid::new())
     }
 }
 
 impl FromCursor for BodyResResultVoid {
-    fn from_cursor(mut _cursor: &mut Cursor<&[u8]>) -> BodyResResultVoid {
-        BodyResResultVoid::new()
+    fn from_cursor(mut _cursor: &mut Cursor<&[u8]>) -> error::Result<BodyResResultVoid> {
+        Ok(BodyResResultVoid::new())
     }
 }
 
@@ -164,8 +174,8 @@ impl BodyResResultSetKeyspace {
 }
 
 impl FromCursor for BodyResResultSetKeyspace {
-    fn from_cursor(mut cursor: &mut Cursor<&[u8]>) -> BodyResResultSetKeyspace {
-        BodyResResultSetKeyspace::new(CString::from_cursor(&mut cursor))
+    fn from_cursor(mut cursor: &mut Cursor<&[u8]>) -> error::Result<BodyResResultSetKeyspace> {
+        CString::from_cursor(&mut cursor).map(|ks| BodyResResultSetKeyspace::new(ks))
     }
 }
 
@@ -191,7 +201,8 @@ impl BodyResResultRows {
         (0..rows_count)
             .map(|_| {
                      (0..columns_count)
-                         .map(|_| CBytes::from_cursor(&mut cursor) as CBytes)
+                     // XXX unwrap()
+                         .map(|_| CBytes::from_cursor(&mut cursor).unwrap() as CBytes)
                          .collect()
                  })
             .collect()
@@ -199,16 +210,17 @@ impl BodyResResultRows {
 }
 
 impl FromCursor for BodyResResultRows {
-    fn from_cursor(mut cursor: &mut Cursor<&[u8]>) -> BodyResResultRows {
-        let metadata = RowsMetadata::from_cursor(&mut cursor);
-        let rows_count = CInt::from_cursor(&mut cursor);
+    fn from_cursor(mut cursor: &mut Cursor<&[u8]>) -> error::Result<BodyResResultRows> {
+        let metadata = RowsMetadata::from_cursor(&mut cursor)?;
+        let rows_count = CInt::from_cursor(&mut cursor)?;
         let rows_content: Vec<Vec<CBytes>> =
             BodyResResultRows::get_rows_content(&mut cursor, rows_count, metadata.columns_count);
-        BodyResResultRows {
-            metadata: metadata,
-            rows_count: rows_count,
-            rows_content: rows_content,
-        }
+
+        Ok(BodyResResultRows {
+               metadata: metadata,
+               rows_count: rows_count,
+               rows_content: rows_content,
+           })
     }
 }
 
@@ -232,32 +244,32 @@ pub struct RowsMetadata {
 }
 
 impl FromCursor for RowsMetadata {
-    fn from_cursor(mut cursor: &mut Cursor<&[u8]>) -> RowsMetadata {
-        let flags = CInt::from_cursor(&mut cursor);
-        let columns_count = CInt::from_cursor(&mut cursor);
+    fn from_cursor(mut cursor: &mut Cursor<&[u8]>) -> error::Result<RowsMetadata> {
+        let flags = CInt::from_cursor(&mut cursor)?;
+        let columns_count = CInt::from_cursor(&mut cursor)?;
 
         let mut paging_state: Option<CBytes> = None;
         if RowsMetadataFlag::has_has_more_pages(flags) {
-            paging_state = Some(CBytes::from_cursor(&mut cursor))
+            paging_state = Some(CBytes::from_cursor(&mut cursor)?)
         }
 
         let mut global_table_space: Option<Vec<CString>> = None;
         let has_global_table_space = RowsMetadataFlag::has_global_table_space(flags);
         if has_global_table_space {
-            let keyspace = CString::from_cursor(&mut cursor);
-            let tablename = CString::from_cursor(&mut cursor);
+            let keyspace = CString::from_cursor(&mut cursor)?;
+            let tablename = CString::from_cursor(&mut cursor)?;
             global_table_space = Some(vec![keyspace, tablename])
         }
 
         let col_specs = ColSpec::parse_colspecs(&mut cursor, columns_count, has_global_table_space);
 
-        RowsMetadata {
-            flags: flags,
-            columns_count: columns_count,
-            paging_state: paging_state,
-            global_table_space: global_table_space,
-            col_specs: col_specs,
-        }
+        Ok(RowsMetadata {
+               flags: flags,
+               columns_count: columns_count,
+               paging_state: paging_state,
+               global_table_space: global_table_space,
+               col_specs: col_specs,
+           })
     }
 }
 
@@ -315,16 +327,16 @@ impl IntoBytes for RowsMetadataFlag {
 }
 
 impl FromBytes for RowsMetadataFlag {
-    fn from_bytes(bytes: &[u8]) -> RowsMetadataFlag {
-        match from_bytes(bytes) as i32 {
-            GLOBAL_TABLE_SPACE => RowsMetadataFlag::GlobalTableSpace,
-            HAS_MORE_PAGES => RowsMetadataFlag::HasMorePages,
-            NO_METADATA => RowsMetadataFlag::NoMetadata,
-            _ => {
-                error!("Unexpected Cassandra rows metadata flag: {:?}", bytes);
-                panic!("Unexpected Cassandra rows metadata flag: {:?}", bytes);
-            }
-        }
+    fn from_bytes(bytes: &[u8]) -> error::Result<RowsMetadataFlag> {
+        try_from_bytes(bytes)
+            .map_err(Into::into)
+            .map(|f| match f as i32 {
+                     GLOBAL_TABLE_SPACE => RowsMetadataFlag::GlobalTableSpace,
+                     HAS_MORE_PAGES => RowsMetadataFlag::HasMorePages,
+                     NO_METADATA => RowsMetadataFlag::NoMetadata,
+                     // TODO: return error
+                     _ => unreachable!(),
+                 })
     }
 }
 
@@ -356,11 +368,13 @@ impl ColSpec {
                 let mut ksname: Option<CString> = None;
                 let mut tablename: Option<CString> = None;
                 if !with_globale_table_spec {
-                    ksname = Some(CString::from_cursor(&mut cursor));
-                    tablename = Some(CString::from_cursor(&mut cursor));
+                    // XXX unwrap
+                    ksname = Some(CString::from_cursor(&mut cursor).unwrap());
+                    tablename = Some(CString::from_cursor(&mut cursor).unwrap());
                 }
-                let name = CString::from_cursor(&mut cursor);
-                let col_type = ColTypeOption::from_cursor(&mut cursor);
+                // XXX unwrap
+                let name = CString::from_cursor(&mut cursor).unwrap();
+                let col_type = ColTypeOption::from_cursor(&mut cursor).unwrap();
 
                 ColSpec {
                     ksname: ksname,
@@ -405,42 +419,44 @@ pub enum ColType {
 }
 
 impl FromBytes for ColType {
-    fn from_bytes(bytes: &[u8]) -> ColType {
-        match from_bytes(bytes) {
-            0x0000 => ColType::Custom,
-            0x0001 => ColType::Ascii,
-            0x0002 => ColType::Bigint,
-            0x0003 => ColType::Blob,
-            0x0004 => ColType::Boolean,
-            0x0005 => ColType::Counter,
-            0x0006 => ColType::Decimal,
-            0x0007 => ColType::Double,
-            0x0008 => ColType::Float,
-            0x0009 => ColType::Int,
-            0x000B => ColType::Timestamp,
-            0x000C => ColType::Uuid,
-            0x000D => ColType::Varchar,
-            0x000E => ColType::Varint,
-            0x000F => ColType::Timeuuid,
-            0x0010 => ColType::Inet,
-            0x0011 => ColType::Date,
-            0x0012 => ColType::Time,
-            0x0013 => ColType::Smallint,
-            0x0014 => ColType::Tinyint,
-            0x0020 => ColType::List,
-            0x0021 => ColType::Map,
-            0x0022 => ColType::Set,
-            0x0030 => ColType::Udt,
-            0x0031 => ColType::Tuple,
-            _ => unreachable!(),
-        }
+    fn from_bytes(bytes: &[u8]) -> error::Result<ColType> {
+        try_from_bytes(bytes)
+            .map_err(Into::into)
+            .map(|b| match b {
+                     0x0000 => ColType::Custom,
+                     0x0001 => ColType::Ascii,
+                     0x0002 => ColType::Bigint,
+                     0x0003 => ColType::Blob,
+                     0x0004 => ColType::Boolean,
+                     0x0005 => ColType::Counter,
+                     0x0006 => ColType::Decimal,
+                     0x0007 => ColType::Double,
+                     0x0008 => ColType::Float,
+                     0x0009 => ColType::Int,
+                     0x000B => ColType::Timestamp,
+                     0x000C => ColType::Uuid,
+                     0x000D => ColType::Varchar,
+                     0x000E => ColType::Varint,
+                     0x000F => ColType::Timeuuid,
+                     0x0010 => ColType::Inet,
+                     0x0011 => ColType::Date,
+                     0x0012 => ColType::Time,
+                     0x0013 => ColType::Smallint,
+                     0x0014 => ColType::Tinyint,
+                     0x0020 => ColType::List,
+                     0x0021 => ColType::Map,
+                     0x0022 => ColType::Set,
+                     0x0030 => ColType::Udt,
+                     0x0031 => ColType::Tuple,
+                     // TODO: should be error
+                     _ => unreachable!(),
+                 })
     }
 }
 
 impl FromCursor for ColType {
-    fn from_cursor(mut cursor: &mut Cursor<&[u8]>) -> ColType {
+    fn from_cursor(mut cursor: &mut Cursor<&[u8]>) -> error::Result<ColType> {
         ColType::from_bytes(cursor_next_value(&mut cursor, SHORT_LEN as u64).as_slice())
-
     }
 }
 
@@ -456,31 +472,33 @@ pub struct ColTypeOption {
 }
 
 impl FromCursor for ColTypeOption {
-    fn from_cursor(mut cursor: &mut Cursor<&[u8]>) -> ColTypeOption {
-        let id = ColType::from_cursor(&mut cursor);
+    fn from_cursor(mut cursor: &mut Cursor<&[u8]>) -> error::Result<ColTypeOption> {
+        let id = ColType::from_cursor(&mut cursor)?;
         let value = match id {
-            ColType::Custom => Some(ColTypeOptionValue::CString(CString::from_cursor(&mut cursor))),
+            ColType::Custom => {
+                Some(ColTypeOptionValue::CString(CString::from_cursor(&mut cursor)?))
+            }
             ColType::Set => {
-                let col_type = ColTypeOption::from_cursor(&mut cursor);
+                let col_type = ColTypeOption::from_cursor(&mut cursor)?;
                 Some(ColTypeOptionValue::CSet(Box::new(col_type)))
             }
             ColType::List => {
-                let col_type = ColTypeOption::from_cursor(&mut cursor);
+                let col_type = ColTypeOption::from_cursor(&mut cursor)?;
                 Some(ColTypeOptionValue::CList(Box::new(col_type)))
             }
-            ColType::Udt => Some(ColTypeOptionValue::UdtType(CUdt::from_cursor(&mut cursor))),
+            ColType::Udt => Some(ColTypeOptionValue::UdtType(CUdt::from_cursor(&mut cursor)?)),
             ColType::Map => {
-                let name_type = ColTypeOption::from_cursor(&mut cursor);
-                let value_type = ColTypeOption::from_cursor(&mut cursor);
+                let name_type = ColTypeOption::from_cursor(&mut cursor)?;
+                let value_type = ColTypeOption::from_cursor(&mut cursor)?;
                 Some(ColTypeOptionValue::CMap((Box::new(name_type), Box::new(value_type))))
             }
             _ => None,
         };
 
-        ColTypeOption {
-            id: id,
-            value: value,
-        }
+        Ok(ColTypeOption {
+               id: id,
+               value: value,
+           })
     }
 }
 
@@ -508,23 +526,24 @@ pub struct CUdt {
 }
 
 impl FromCursor for CUdt {
-    fn from_cursor(mut cursor: &mut Cursor<&[u8]>) -> CUdt {
-        let ks = CString::from_cursor(&mut cursor);
-        let udt_name = CString::from_cursor(&mut cursor);
-        let n = from_bytes(cursor_next_value(&mut cursor, SHORT_LEN as u64).as_slice());
+    fn from_cursor(mut cursor: &mut Cursor<&[u8]>) -> error::Result<CUdt> {
+        let ks = CString::from_cursor(&mut cursor)?;
+        let udt_name = CString::from_cursor(&mut cursor)?;
+        let n = try_from_bytes(cursor_next_value(&mut cursor, SHORT_LEN as u64).as_slice())?;
         let descriptions: Vec<(CString, ColTypeOption)> = (0..n)
             .map(|_| {
-                     let name = CString::from_cursor(&mut cursor);
-                     let col_type = ColTypeOption::from_cursor(&mut cursor);
+                     // XXX unwrap
+                     let name = CString::from_cursor(&mut cursor).unwrap();
+                     let col_type = ColTypeOption::from_cursor(&mut cursor).unwrap();
                      (name, col_type)
                  })
             .collect();
 
-        CUdt {
-            ks: ks,
-            udt_name: udt_name,
-            descriptions: descriptions,
-        }
+        Ok(CUdt {
+               ks: ks,
+               udt_name: udt_name,
+               descriptions: descriptions,
+           })
     }
 }
 
@@ -541,16 +560,16 @@ pub struct BodyResResultPrepared {
 }
 
 impl FromCursor for BodyResResultPrepared {
-    fn from_cursor(mut cursor: &mut Cursor<&[u8]>) -> BodyResResultPrepared {
-        let id = CBytesShort::from_cursor(&mut cursor);
-        let metadata = PreparedMetadata::from_cursor(&mut cursor);
-        let result_metadata = RowsMetadata::from_cursor(&mut cursor);
-
-        BodyResResultPrepared {
-            id: id,
-            metadata: metadata,
-            result_metadata: result_metadata,
-        }
+    fn from_cursor(mut cursor: &mut Cursor<&[u8]>) -> error::Result<BodyResResultPrepared> {
+        let id = CBytesShort::from_cursor(&mut cursor)?;
+        let metadata = PreparedMetadata::from_cursor(&mut cursor)?;
+        let result_metadata = RowsMetadata::from_cursor(&mut cursor)?;
+
+        Ok(BodyResResultPrepared {
+               id: id,
+               metadata: metadata,
+               result_metadata: result_metadata,
+           })
     }
 }
 
@@ -566,32 +585,34 @@ pub struct PreparedMetadata {
 }
 
 impl FromCursor for PreparedMetadata {
-    fn from_cursor(mut cursor: &mut Cursor<&[u8]>) -> PreparedMetadata {
-        let flags = CInt::from_cursor(&mut cursor);
-        let columns_count = CInt::from_cursor(&mut cursor);
-        let pk_count = CInt::from_cursor(&mut cursor);
+    fn from_cursor(mut cursor: &mut Cursor<&[u8]>) -> error::Result<PreparedMetadata> {
+        let flags = CInt::from_cursor(&mut cursor)?;
+        let columns_count = CInt::from_cursor(&mut cursor)?;
+        let pk_count = CInt::from_cursor(&mut cursor)?;
         let pk_indexes: Vec<i16> = (0..pk_count).fold(vec![], |mut acc, _| {
-            let idx = from_bytes(cursor_next_value(&mut cursor, SHORT_LEN as u64).as_slice()) as
-                      i16;
+            // XXX unwrap
+            let idx = try_from_bytes(cursor_next_value(&mut cursor, SHORT_LEN as u64)
+                                         .as_slice())
+                    .unwrap() as i16;
             acc.push(idx);
             acc
         });
         let mut global_table_space: Option<(CString, CString)> = None;
         let has_global_table_space = RowsMetadataFlag::has_global_table_space(flags);
         if has_global_table_space {
-            let keyspace = CString::from_cursor(&mut cursor);
-            let tablename = CString::from_cursor(&mut cursor);
+            let keyspace = CString::from_cursor(&mut cursor)?;
+            let tablename = CString::from_cursor(&mut cursor)?;
             global_table_space = Some((keyspace, tablename))
         }
         let col_specs = ColSpec::parse_colspecs(&mut cursor, columns_count, has_global_table_space);
 
-        PreparedMetadata {
-            flags: flags,
-            columns_count: columns_count,
-            pk_count: pk_count,
-            pk_indexes: pk_indexes,
-            global_table_spec: global_table_space,
-            col_specs: col_specs,
-        }
+        Ok(PreparedMetadata {
+               flags: flags,
+               columns_count: columns_count,
+               pk_count: pk_count,
+               pk_indexes: pk_indexes,
+               global_table_spec: global_table_space,
+               col_specs: col_specs,
+           })
     }
 }
diff --git a/src/frame/frame_supported.rs b/src/frame/frame_supported.rs
index 5e7c1bc..0f1ba50 100644
--- a/src/frame/frame_supported.rs
+++ b/src/frame/frame_supported.rs
@@ -1,7 +1,9 @@
 use std::collections::HashMap;
 use std::io::Cursor;
+
 use FromCursor;
-use types::{SHORT_LEN, cursor_next_value, from_bytes, CString, CStringList};
+use error;
+use types::{SHORT_LEN, cursor_next_value, try_from_bytes, CString, CStringList};
 
 #[derive(Debug)]
 pub struct BodyResSupported {
@@ -9,17 +11,20 @@ pub struct BodyResSupported {
 }
 
 impl FromCursor for BodyResSupported {
-    fn from_cursor(mut cursor: &mut Cursor<&[u8]>) -> BodyResSupported {
-        let l = from_bytes(cursor_next_value(&mut cursor, SHORT_LEN as u64).as_slice()) as i16;
+    fn from_cursor(mut cursor: &mut Cursor<&[u8]>) -> error::Result<BodyResSupported> {
+        let l = try_from_bytes(cursor_next_value(&mut cursor, SHORT_LEN as u64).as_slice())? as i16;
         let acc: HashMap<String, Vec<String>> = HashMap::new();
         let map = (0..l).fold(acc, |mut m, _| {
-            let name = CString::from_cursor(&mut cursor).into_plain();
-            let val = CStringList::from_cursor(&mut cursor).into_plain();
+            // XXX unwrap()
+            let name = CString::from_cursor(&mut cursor).unwrap().into_plain();
+            let val = CStringList::from_cursor(&mut cursor)
+                .unwrap()
+                .into_plain();
             m.insert(name, val);
             m
         });
 
-        BodyResSupported { data: map }
+        Ok(BodyResSupported { data: map })
     }
 }
 
@@ -47,7 +52,7 @@ mod tests {
                      1,
                      98 /* value ["a", "b"] */];
         let mut cursor: Cursor<&[u8]> = Cursor::new(&bytes);
-        let options = BodyResSupported::from_cursor(&mut cursor).data;
+        let options = BodyResSupported::from_cursor(&mut cursor).unwrap().data;
         assert_eq!(options.len(), 1);
         let option_ab = options.get(&"ab".to_string()).unwrap();
         assert_eq!(option_ab[0], "a".to_string());
diff --git a/src/frame/mod.rs b/src/frame/mod.rs
index 4c92b7f..9b10fa3 100644
--- a/src/frame/mod.rs
+++ b/src/frame/mod.rs
@@ -50,7 +50,7 @@ pub struct Frame {
 }
 
 impl Frame {
-    pub fn get_body(&self) -> ResponseBody {
+    pub fn get_body(&self) -> error::Result<ResponseBody> {
         ResponseBody::from(self.body.as_slice(), &self.opcode)
     }
 
diff --git a/src/frame/parser.rs b/src/frame/parser.rs
index e4b874c..9b44800 100644
--- a/src/frame/parser.rs
+++ b/src/frame/parser.rs
@@ -58,7 +58,7 @@ pub fn parse_frame(mut cursor: &mut Read, compressor: &Compression) -> error::Re
     };
 
     let warnings = if flags.iter().any(|flag| flag == &Flag::Warning) {
-        CStringList::from_cursor(&mut body_cursor).into_plain()
+        CStringList::from_cursor(&mut body_cursor)?.into_plain()
     } else {
         vec![]
     };
@@ -83,10 +83,12 @@ pub fn parse_frame(mut cursor: &mut Read, compressor: &Compression) -> error::Re
 fn conver_frame_into_result(frame: Frame) -> error::Result<Frame> {
     match frame.opcode {
         Opcode::Error => {
-            match frame.get_body() {
-                ResponseBody::Error(err) => Err(error::Error::Server(err)),
-                _ => unreachable!(),
-            }
+            frame
+                .get_body()
+                .and_then(|err| match err {
+                              ResponseBody::Error(err) => Err(error::Error::Server(err)),
+                              _ => unreachable!(),
+                          })
         }
         _ => Ok(frame),
     }
diff --git a/src/lib.rs b/src/lib.rs
index 9cebafb..d4b5bb8 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -37,7 +37,7 @@ pub trait IntoBytes {
 /// `FromBytes` should be used to parse an array of bytes into a structure.
 pub trait FromBytes {
     /// It gets and array of bytes and should return an implementor struct.
-    fn from_bytes(&[u8]) -> Self;
+    fn from_bytes(&[u8]) -> error::Result<Self> where Self: Sized;
 }
 
 /// `AsBytes` should be used to convert a value into a single byte.
@@ -57,5 +57,5 @@ pub trait FromSingleByte {
 /// wich bound to an array of bytes.
 pub trait FromCursor {
     /// It should return an implementor from an `io::Cursor` over an array of bytes.
-    fn from_cursor(&mut Cursor<&[u8]>) -> Self;
+    fn from_cursor(&mut Cursor<&[u8]>) -> error::Result<Self> where Self: Sized;
 }
diff --git a/src/types/data_serialization_types.rs b/src/types/data_serialization_types.rs
index 57913b0..73dc65a 100644
--- a/src/types/data_serialization_types.rs
+++ b/src/types/data_serialization_types.rs
@@ -75,8 +75,8 @@ pub fn decode_decimal(bytes: &[u8]) -> Result<f32, io::Error> {
         return Err(scaled.unwrap_err());
     }
 
-    let unscaled_unwrapped: f32 = unscaled.unwrap() as f32;
-    let scaled_unwrapped: i32 = scaled.unwrap() as i32;
+    let unscaled_unwrapped = try!(unscaled) as f32;
+    let scaled_unwrapped = try!(scaled) as i32;
     let dec: f32 = 10.0;
     Ok(unscaled_unwrapped.mul(dec.powi(scaled_unwrapped)))
 }
@@ -123,9 +123,11 @@ pub fn decode_timestamp(bytes: &[u8]) -> Result<i64, io::Error> {
 // Decodes Cassandra `list` data (bytes) into Rust's `Result<Vec<CBytes>, io::Error>`
 pub fn decode_list(bytes: &[u8]) -> Result<Vec<CBytes>, io::Error> {
     let mut cursor: io::Cursor<&[u8]> = io::Cursor::new(bytes);
-    let l = CInt::from_cursor(&mut cursor);
+    let l =
+        CInt::from_cursor(&mut cursor).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;
     let list = (0..l)
-        .map(|_| CBytes::from_cursor(&mut cursor))
+    // XXX unwrap
+        .map(|_| CBytes::from_cursor(&mut cursor).unwrap())
         .collect();
     Ok(list)
 }
@@ -138,9 +140,12 @@ pub fn decode_set(bytes: &[u8]) -> Result<Vec<CBytes>, io::Error> {
 // Decodes Cassandra `map` data (bytes) into Rust's `Result<Vec<(CBytes, CBytes)>, io::Error>`
 pub fn decode_map(bytes: &[u8]) -> Result<Vec<(CBytes, CBytes)>, io::Error> {
     let mut cursor: io::Cursor<&[u8]> = io::Cursor::new(bytes);
-    let l = CInt::from_cursor(&mut cursor);
+    let l = CInt::from_cursor(&mut cursor)
+        .map_err(|err| io::Error::new(io::ErrorKind::InvalidData, err))?;
     let list = (0..l)
-        .map(|_| (CBytes::from_cursor(&mut cursor), CBytes::from_cursor(&mut cursor)))
+        // XXX: unwrap
+        .map(|_| (CBytes::from_cursor(&mut cursor).unwrap(),
+            CBytes::from_cursor(&mut cursor).unwrap()))
         .collect();
     Ok(list)
 }
@@ -180,7 +185,8 @@ pub fn decode_varint(bytes: &[u8]) -> Result<i64, io::Error> {
 pub fn decode_udt(bytes: &[u8], l: usize) -> Result<Vec<CBytes>, io::Error> {
     let mut cursor: io::Cursor<&[u8]> = io::Cursor::new(bytes);
     let list = (0..l)
-        .map(|_| CBytes::from_cursor(&mut cursor))
+    // XXX unwrap
+        .map(|_| CBytes::from_cursor(&mut cursor).unwrap())
         .collect();
     Ok(list)
 }
diff --git a/src/types/list.rs b/src/types/list.rs
index 1dacaee..ddd06e9 100644
--- a/src/types/list.rs
+++ b/src/types/list.rs
@@ -37,6 +37,7 @@ impl AsRust<Vec<Vec<u8>>> for List {
         match self.metadata.value {
             Some(ColTypeOptionValue::CList(ref type_option)) => {
                 match type_option.id {
+                    // XXX unwrap
                     ColType::Blob => Ok(self.map(|bytes| decode_blob(bytes.as_plain()).unwrap())),
                     _ => unreachable!(),
                 }
@@ -60,6 +61,7 @@ macro_rules! list_as_rust {
                     Some(ColTypeOptionValue::CList(ref type_option)) |
                     Some(ColTypeOptionValue::CSet(ref type_option)) => {
                         let type_option_ref = type_option.as_ref();
+                        // XXX unwrap
                         let convert = self
                             .map(|bytes| as_rust!(type_option_ref, bytes, $($into_type)*).unwrap());
 
diff --git a/src/types/mod.rs b/src/types/mod.rs
index 6098d68..c3b3e9d 100644
--- a/src/types/mod.rs
+++ b/src/types/mod.rs
@@ -41,6 +41,10 @@ pub fn try_to_n_bytes(int: u64, n: usize) -> io::Result<Vec<u8>> {
 }
 
 /// Converts u64 numerical value into array of n bytes
+///
+/// # Panics
+///
+/// It panics if given unisigned integer could not be converted in an array of n bytes
 pub fn to_n_bytes(int: u64, n: usize) -> Vec<u8> {
     try_to_n_bytes(int, n).unwrap()
 }
@@ -55,6 +59,11 @@ pub fn try_i_to_n_bytes(int: i64, n: usize) -> io::Result<Vec<u8>> {
     Ok(bytes)
 }
 
+/// Converts u64 numerical value into array of n bytes
+///
+/// # Panics
+///
+/// It panics if given integer could not be converted in an array of n bytes
 pub fn i_to_n_bytes(int: i64, n: usize) -> Vec<u8> {
     try_i_to_n_bytes(int, n).unwrap()
 }
@@ -104,21 +113,37 @@ pub fn try_f64_from_bytes(bytes: &[u8]) -> Result<f64, io::Error> {
 }
 
 /// Converts byte-array into u64
+///
+/// # Panics
+///
+/// It panics if given bytes could not be converted into `u64`
 pub fn from_bytes(bytes: &[u8]) -> u64 {
     try_from_bytes(bytes).unwrap()
 }
 
 /// Converts byte-array into i64
+///
+/// # Panics
+///
+/// It panics if given bytes could not be converted into `i64`
 pub fn from_i_bytes(bytes: &[u8]) -> i64 {
     try_i_from_bytes(bytes).unwrap()
 }
 
 /// Converts byte-array into u16
+///
+/// # Panics
+///
+/// It panics if given bytes could not be converted into `u16`
 pub fn from_u16_bytes(bytes: &[u8]) -> u16 {
     try_u16_from_bytes(bytes).unwrap()
 }
 
 /// Converts number i16 into Cassandra's [short].
+///
+/// # Panics
+///
+/// It panics if given `i16` could not be converted into bytes
 pub fn to_short(int: i16) -> Vec<u8> {
     let mut bytes = vec![];
     // should not panic as input is i16
@@ -128,6 +153,10 @@ pub fn to_short(int: i16) -> Vec<u8> {
 }
 
 /// Convers integer into Cassandra's [int]
+///
+/// # Panics
+///
+/// It panics if given `i32` could not be converted into bytes
 pub fn to_int(int: i32) -> Vec<u8> {
     let mut bytes = vec![];
     // should not panic as input is i16
@@ -137,6 +166,10 @@ pub fn to_int(int: i32) -> Vec<u8> {
 }
 
 /// Convers integer into Cassandra's [int]
+///
+/// # Panics
+///
+/// It panics if given `i64` could not be converted into bytes
 pub fn to_bigint(int: i64) -> Vec<u8> {
     let mut bytes = vec![];
     // should not panic as input is i16
@@ -145,7 +178,11 @@ pub fn to_bigint(int: i64) -> Vec<u8> {
     bytes
 }
 
-/// Converts number i16 into Cassandra's [short].
+/// Converts number i16 into Cassandra's `short`.
+///
+/// # Panics
+///
+/// It panics if given `u16` could not be converted into bytes
 pub fn to_u_short(int: u16) -> Vec<u8> {
     let mut bytes = vec![];
     // should not panic as input is i16
@@ -155,6 +192,10 @@ pub fn to_u_short(int: u16) -> Vec<u8> {
 }
 
 /// Convers integer into Cassandra's [int]
+///
+/// # Panics
+///
+/// It panics if given `u32` could not be converted into bytes
 pub fn to_u(int: u32) -> Vec<u8> {
     let mut bytes = vec![];
     // should not panic as input is u64
@@ -163,7 +204,11 @@ pub fn to_u(int: u32) -> Vec<u8> {
     bytes
 }
 
-/// Convers integer into Cassandra's [int]
+/// Convers integer into Cassandra's `int`
+///
+/// # Panics
+///
+/// It panics if given `u64` could not be converted into `u64`
 pub fn to_u_big(int: u64) -> Vec<u8> {
     let mut bytes = vec![];
     // should not panic as input is u64
@@ -172,6 +217,11 @@ pub fn to_u_big(int: u64) -> Vec<u8> {
     bytes
 }
 
+/// Converts `f32` into bytes
+///
+/// # Panics
+///
+/// It panics if given `f32` could not be converted into bytes
 pub fn to_float(f: f32) -> Vec<u8> {
     let mut bytes = vec![];
     // should not panic as input is f32
@@ -180,6 +230,11 @@ pub fn to_float(f: f32) -> Vec<u8> {
     bytes
 }
 
+/// Converts `f64` into array of bytes
+///
+/// # Panics
+///
+/// It panics if given `f63` could not be converted into bytes
 pub fn to_float_big(f: f64) -> Vec<u8> {
     let mut bytes = vec![];
     // should not panic as input is f64
@@ -230,12 +285,14 @@ impl IntoBytes for CString {
 impl FromCursor for CString {
     /// from_cursor gets Cursor who's position is set such that it should be a start of a [string].
     /// It reads required number of bytes and returns a String
-    fn from_cursor(mut cursor: &mut Cursor<&[u8]>) -> CString {
+    fn from_cursor(mut cursor: &mut Cursor<&[u8]>) -> CDRSResult<CString> {
         let len_bytes = cursor_next_value(&mut cursor, SHORT_LEN as u64);
-        let len: u64 = from_bytes(len_bytes.as_slice());
+        let len: u64 = try_from_bytes(len_bytes.as_slice())?;
         let body_bytes = cursor_next_value(&mut cursor, len);
 
-        CString { string: String::from_utf8(body_bytes).unwrap() }
+        String::from_utf8(body_bytes)
+            .map_err(Into::into)
+            .map(CString::new)
     }
 }
 
@@ -276,12 +333,14 @@ impl IntoBytes for CStringLong {
 impl FromCursor for CStringLong {
     /// from_cursor gets Cursor who's position is set such that it should be a start of a [string].
     /// It reads required number of bytes and returns a String
-    fn from_cursor(mut cursor: &mut Cursor<&[u8]>) -> CStringLong {
+    fn from_cursor(mut cursor: &mut Cursor<&[u8]>) -> CDRSResult<CStringLong> {
         let len_bytes = cursor_next_value(&mut cursor, INT_LEN as u64);
-        let len: u64 = from_bytes(len_bytes.as_slice());
+        let len: u64 = try_from_bytes(len_bytes.as_slice())?;
         let body_bytes = cursor_next_value(&mut cursor, len);
 
-        CStringLong { string: String::from_utf8(body_bytes).unwrap() }
+        String::from_utf8(body_bytes)
+            .map_err(Into::into)
+            .map(CStringLong::new)
     }
 }
 
@@ -318,18 +377,17 @@ impl IntoBytes for CStringList {
 }
 
 impl FromCursor for CStringList {
-    fn from_cursor(mut cursor: &mut Cursor<&[u8]>) -> CStringList {
+    fn from_cursor(mut cursor: &mut Cursor<&[u8]>) -> CDRSResult<CStringList> {
         // TODO: try to use slice instead
         let mut len_bytes = [0; SHORT_LEN];
-        if let Err(err) = cursor.read(&mut len_bytes) {
-            error!("Read Cassandra bytes error: {}", err);
-            panic!(err);
-        }
-        let len: u64 = from_bytes(len_bytes.to_vec().as_slice());
+        try!(cursor.read(&mut len_bytes));
+        let len: u64 = try_from_bytes(len_bytes.to_vec().as_slice())?;
         let list = (0..len)
-            .map(|_| CString::from_cursor(&mut cursor))
+        // XXX unwrap
+            .map(|_| CString::from_cursor(&mut cursor).unwrap())
             .collect();
-        CStringList { list: list }
+
+        Ok(CStringList { list: list })
     }
 }
 
@@ -364,13 +422,14 @@ impl CBytes {
 impl FromCursor for CBytes {
     /// from_cursor gets Cursor who's position is set such that it should be a start of a [bytes].
     /// It reads required number of bytes and returns a CBytes
-    fn from_cursor(mut cursor: &mut Cursor<&[u8]>) -> CBytes {
-        let len = CInt::from_cursor(&mut cursor);
+    fn from_cursor(mut cursor: &mut Cursor<&[u8]>) -> CDRSResult<CBytes> {
+        let len = CInt::from_cursor(&mut cursor)?;
         // null or not set value
         if len < 0 {
-            return CBytes { bytes: vec![] };
+            return Ok(CBytes { bytes: vec![] });
         }
-        CBytes { bytes: cursor_next_value(&mut cursor, len as u64) }
+
+        Ok(CBytes { bytes: cursor_next_value(&mut cursor, len as u64) })
     }
 }
 
@@ -404,9 +463,10 @@ impl CBytesShort {
 impl FromCursor for CBytesShort {
     /// from_cursor gets Cursor who's position is set such that it should be a start of a [bytes].
     /// It reads required number of bytes and returns a CBytes
-    fn from_cursor(mut cursor: &mut Cursor<&[u8]>) -> CBytesShort {
-        let len: u64 = CIntShort::from_cursor(&mut cursor) as u64;
-        CBytesShort { bytes: cursor_next_value(&mut cursor, len) }
+    fn from_cursor(mut cursor: &mut Cursor<&[u8]>) -> CDRSResult<CBytesShort> {
+        let len: u64 = CIntShort::from_cursor(&mut cursor)? as u64;
+
+        Ok(CBytesShort { bytes: cursor_next_value(&mut cursor, len) })
     }
 }
 
@@ -426,9 +486,9 @@ impl IntoBytes for CBytesShort {
 pub type CInt = i32;
 
 impl FromCursor for CInt {
-    fn from_cursor(mut cursor: &mut Cursor<&[u8]>) -> CInt {
+    fn from_cursor(mut cursor: &mut Cursor<&[u8]>) -> CDRSResult<CInt> {
         let bytes = cursor_next_value(&mut cursor, INT_LEN as u64);
-        try_i32_from_bytes(bytes.as_slice()).unwrap() as CInt
+        try_i32_from_bytes(bytes.as_slice()).map_err(Into::into)
     }
 }
 
@@ -436,19 +496,20 @@ impl FromCursor for CInt {
 pub type CIntShort = i16;
 
 impl FromCursor for CIntShort {
-    fn from_cursor(mut cursor: &mut Cursor<&[u8]>) -> CIntShort {
+    fn from_cursor(mut cursor: &mut Cursor<&[u8]>) -> CDRSResult<CIntShort> {
         let bytes = cursor_next_value(&mut cursor, SHORT_LEN as u64);
-        try_i16_from_bytes(bytes.as_slice()).unwrap() as CIntShort
+        try_i16_from_bytes(bytes.as_slice()).map_err(Into::into)
     }
 }
 
 // Use extended Rust Vec<u8> as Cassandra [bytes]
 impl FromBytes for Vec<u8> {
-    fn from_bytes(bytes: &[u8]) -> Vec<u8> {
+    fn from_bytes(bytes: &[u8]) -> CDRSResult<Vec<u8>> {
         let mut cursor = Cursor::new(bytes);
         let len_bytes = cursor_next_value(&mut cursor, SHORT_LEN as u64);
-        let len: u64 = from_bytes(len_bytes.as_slice());
-        cursor_next_value(&mut cursor, len)
+        let len: u64 = try_from_bytes(len_bytes.as_slice())?;
+
+        Ok(cursor_next_value(&mut cursor, len))
     }
 }
 
@@ -460,13 +521,13 @@ pub struct CInet {
 }
 
 impl FromCursor for CInet {
-    fn from_cursor(mut cursor: &mut Cursor<&[u8]>) -> CInet {
-        let n = CIntShort::from_cursor(&mut cursor);
-        let ip = decode_inet(cursor_next_value(&mut cursor, n as u64).as_slice()).unwrap();
-        let port = CInt::from_cursor(&mut cursor);
+    fn from_cursor(mut cursor: &mut Cursor<&[u8]>) -> CDRSResult<CInet> {
+        let n = CIntShort::from_cursor(&mut cursor)?;
+        let ip = decode_inet(cursor_next_value(&mut cursor, n as u64).as_slice())?;
+        let port = CInt::from_cursor(&mut cursor)?;
         let socket_addr = SocketAddr::new(ip, port as u16);
 
-        CInet { addr: socket_addr }
+        Ok(CInet { addr: socket_addr })
     }
 }
 
@@ -528,8 +589,7 @@ mod tests {
     fn test_cstring_from_cursor() {
         let a = &[0, 3, 102, 111, 111, 0];
         let mut cursor: Cursor<&[u8]> = Cursor::new(a);
-        let cstring = CString::from_cursor(&mut cursor);
-        println!("{:?}", &cursor);
+        let cstring = CString::from_cursor(&mut cursor).unwrap();
         assert_eq!(cstring.as_str(), "foo");
     }
 
@@ -568,8 +628,7 @@ mod tests {
     fn test_cstringlong_from_cursor() {
         let a = &[0, 0, 0, 3, 102, 111, 111, 0];
         let mut cursor: Cursor<&[u8]> = Cursor::new(a);
-        let cstring = CStringLong::from_cursor(&mut cursor);
-        println!("{:?}", &cursor);
+        let cstring = CStringLong::from_cursor(&mut cursor).unwrap();
         assert_eq!(cstring.as_str(), "foo");
     }
 
@@ -578,7 +637,7 @@ mod tests {
     fn test_cstringlist() {
         let a = &[0, 2, 0, 3, 102, 111, 111, 0, 3, 102, 111, 111];
         let mut cursor: Cursor<&[u8]> = Cursor::new(a);
-        let list = CStringList::from_cursor(&mut cursor);
+        let list = CStringList::from_cursor(&mut cursor).unwrap();
         let plain = list.into_plain();
         assert_eq!(plain.len(), 2);
         for s in plain.iter() {
@@ -603,7 +662,7 @@ mod tests {
     fn test_cbytes_from_cursor() {
         let a = &[0, 0, 0, 3, 1, 2, 3];
         let mut cursor: Cursor<&[u8]> = Cursor::new(a);
-        let cbytes = CBytes::from_cursor(&mut cursor);
+        let cbytes = CBytes::from_cursor(&mut cursor).unwrap();
         assert_eq!(cbytes.into_plain(), &[1, 2, 3]);
     }
 
@@ -631,7 +690,7 @@ mod tests {
     fn test_cbytesshort_from_cursor() {
         let a = &[0, 3, 1, 2, 3];
         let mut cursor: Cursor<&[u8]> = Cursor::new(a);
-        let cbytes = CBytesShort::from_cursor(&mut cursor);
+        let cbytes = CBytesShort::from_cursor(&mut cursor).unwrap();
         assert_eq!(cbytes.into_plain(), &[1, 2, 3]);
     }
 
@@ -647,7 +706,7 @@ mod tests {
     fn test_cint_from_cursor() {
         let a = &[0, 0, 0, 5];
         let mut cursor: Cursor<&[u8]> = Cursor::new(a);
-        let i = CInt::from_cursor(&mut cursor);
+        let i = CInt::from_cursor(&mut cursor).unwrap();
         assert_eq!(i, 5);
     }
 
@@ -656,7 +715,7 @@ mod tests {
     fn test_cintshort_from_cursor() {
         let a = &[0, 5];
         let mut cursor: Cursor<&[u8]> = Cursor::new(a);
-        let i = CIntShort::from_cursor(&mut cursor);
+        let i = CIntShort::from_cursor(&mut cursor).unwrap();
         assert_eq!(i, 5);
     }
 


Test patch:
diff --git a/tests/create_insert_table.rs b/tests/create_insert_table.rs
index dd16500..f7c0af1 100644
--- a/tests/create_insert_table.rs
+++ b/tests/create_insert_table.rs
@@ -90,6 +90,7 @@ fn insert_data_users() {
         .prepare(insert_table_cql.to_string(), true, true)
         .unwrap()
         .get_body()
+        .unwrap()
         .into_prepared()
         .unwrap();
 
@@ -120,7 +121,7 @@ fn read_from_user_table() {
 
     match query_op {
         Ok(res) => {
-            let res_body = res.get_body();
+            let res_body = res.get_body().unwrap();
             if let Some(rows) = res_body.into_rows() {
                 let users: Vec<User> = rows.iter()
                     .map(|row| {
diff --git a/tests/crud_operations.rs b/tests/crud_operations.rs
index a08f5c1..6d01f43 100644
--- a/tests/crud_operations.rs
+++ b/tests/crud_operations.rs
@@ -246,6 +246,7 @@ fn prepare_query(session: &mut Session<NoneAuthenticator, TransportTcp>,
         .prepare(query.to_string(), false, false)
         .unwrap()
         .get_body()
+        .unwrap()
         .into_prepared()
         .unwrap()
         .id
@@ -279,6 +280,7 @@ fn select_all_ints(session: &mut Session<NoneAuthenticator, TransportTcp>) -> bo
         .query(select_query, false, false)
         .unwrap()
         .get_body()
+        .unwrap()
         .into_rows()
         .unwrap();
 
@@ -348,6 +350,7 @@ fn select_table_str(session: &mut Session<NoneAuthenticator, TransportTcp>) -> b
         .query(select_query, false, false)
         .unwrap()
         .get_body()
+        .unwrap()
         .into_rows()
         .unwrap();
 
@@ -397,6 +400,7 @@ fn select_table_list(session: &mut Session<NoneAuthenticator, TransportTcp>) ->
         .query(select_query, false, false)
         .unwrap()
         .get_body()
+        .unwrap()
         .into_rows()
         .unwrap();
 
@@ -468,6 +472,7 @@ fn select_table_map(session: &mut Session<NoneAuthenticator, TransportTcp>) -> b
         .query(select_query, false, false)
         .unwrap()
         .get_body()
+        .unwrap()
         .into_rows()
         .unwrap();
 
@@ -542,6 +547,7 @@ fn select_table_udt(session: &mut Session<NoneAuthenticator, TransportTcp>) -> b
         .query(select_query, false, false)
         .unwrap()
         .get_body()
+        .unwrap()
         .into_rows()
         .unwrap();
 
@@ -579,6 +585,7 @@ fn select_table_bool(session: &mut Session<NoneAuthenticator, TransportTcp>) ->
         .query(select_query, false, false)
         .unwrap()
         .get_body()
+        .unwrap()
         .into_rows()
         .unwrap();
 
@@ -618,6 +625,7 @@ fn select_table_uuid(session: &mut Session<NoneAuthenticator, TransportTcp>) ->
         .query(select_query, false, false)
         .unwrap()
         .get_body()
+        .unwrap()
         .into_rows()
         .unwrap();
 
@@ -656,6 +664,7 @@ fn select_table_float(session: &mut Session<NoneAuthenticator, TransportTcp>) ->
         .query(select_query, false, false)
         .unwrap()
         .get_body()
+        .unwrap()
         .into_rows()
         .unwrap();
 
@@ -695,6 +704,7 @@ fn select_table_blob(session: &mut Session<NoneAuthenticator, TransportTcp>) ->
         .query(select_query, false, false)
         .unwrap()
         .get_body()
+        .unwrap()
         .into_rows()
         .unwrap();