Improve error messages
diff --git a/router.go b/router.go
index 5172c89..155b871 100644
--- a/router.go
+++ b/router.go
@@ -213,7 +213,7 @@
 // communication with a proxy).
 func (r *Router) Handle(method, path string, handle Handle) {
 	if path[0] != '/' {
-		panic("path must begin with '/'")
+		panic("path must begin with '/' in path '" + path + "'")
 	}
 
 	if r.trees == nil {
@@ -257,7 +257,7 @@
 //     router.ServeFiles("/src/*filepath", http.Dir("/var/www"))
 func (r *Router) ServeFiles(path string, root http.FileSystem) {
 	if len(path) < 10 || path[len(path)-10:] != "/*filepath" {
-		panic("path must end with /*filepath")
+		panic("path must end with /*filepath in path '" + path + "'")
 	}
 
 	fileServer := http.FileServer(root)
diff --git a/tree.go b/tree.go
index b741654..a15bc2c 100644
--- a/tree.go
+++ b/tree.go
@@ -7,7 +7,6 @@
 import (
 	"strings"
 	"unicode"
-	"fmt"
 )
 
 func min(a, b int) int {
@@ -79,6 +78,7 @@
 // addRoute adds a node with the given handle to the path.
 // Not concurrency-safe!
 func (n *node) addRoute(path string, handle Handle) {
+	fullPath := path
 	n.priority++
 	numParams := countParams(path)
 
@@ -148,7 +148,9 @@
 						}
 					}
 
-					panic(fmt.Sprintf("conflict with wildcard route. has %q got %q", path, n.path))
+					panic("path segment '" + path +
+						"' conflicts with existing wildcard '" + n.path +
+						"' in path '" + fullPath + "'")
 				}
 
 				c := path[0]
@@ -180,23 +182,23 @@
 					n.incrementChildPrio(len(n.indices) - 1)
 					n = child
 				}
-				n.insertChild(numParams, path, handle)
+				n.insertChild(numParams, path, fullPath, handle)
 				return
 
 			} else if i == len(path) { // Make node a (in-path) leaf
 				if n.handle != nil {
-					panic(fmt.Sprintf("a Handle is already registered for this path (%q)", path))
+					panic("a handle is already registered for path ''" + fullPath + "'")
 				}
 				n.handle = handle
 			}
 			return
 		}
 	} else { // Empty tree
-		n.insertChild(numParams, path, handle)
+		n.insertChild(numParams, path, fullPath, handle)
 	}
 }
 
-func (n *node) insertChild(numParams uint8, path string, handle Handle) {
+func (n *node) insertChild(numParams uint8, path, fullPath string, handle Handle) {
 	var offset int // already handled bytes of the path
 
 	// find prefix until first wildcard (beginning with ':'' or '*'')
@@ -206,27 +208,29 @@
 			continue
 		}
 
-		// check if this Node existing children which would be
-		// unreachable if we insert the wildcard here
-		if len(n.children) > 0 {
-			panic("wildcard route conflicts with existing children")
-		}
-
 		// find wildcard end (either '/' or path end)
 		end := i + 1
 		for end < max && path[end] != '/' {
 			switch path[end] {
 			// the wildcard name must not contain ':' and '*'
 			case ':', '*':
-				panic("only one wildcard per path segment is allowed")
+				panic("only one wildcard per path segment is allowed, has: '" +
+					path[i:] + "' in path '" + fullPath + "'")
 			default:
 				end++
 			}
 		}
 
+		// check if this Node existing children which would be
+		// unreachable if we insert the wildcard here
+		if len(n.children) > 0 {
+			panic("wildcard route '" + path[i:end] +
+				"' conflicts with existing children in path '" + fullPath + "'")
+		}
+
 		// check if the wildcard has a name
 		if end-i < 2 {
-			panic("wildcards must be named with a non-empty name")
+			panic("wildcards must be named with a non-empty name in path '" + fullPath + "'")
 		}
 
 		if c == ':' { // param
@@ -262,17 +266,17 @@
 
 		} else { // catchAll
 			if end != max || numParams > 1 {
-				panic("catch-all routes are only allowed at the end of the path")
+				panic("catch-all routes are only allowed at the end of the path in path '" + fullPath + "'")
 			}
 
 			if len(n.path) > 0 && n.path[len(n.path)-1] == '/' {
-				panic("catch-all conflicts with existing handle for the path segment root")
+				panic("catch-all conflicts with existing handle for the path segment root in path '" + fullPath + "'")
 			}
 
 			// currently fixed width 1 for '/'
 			i--
 			if path[i] != '/' {
-				panic("no / before catch-all")
+				panic("no / before catch-all in path '" + fullPath + "'")
 			}
 
 			n.path = path[offset:i]
@@ -397,7 +401,7 @@
 					return
 
 				default:
-					panic("Invalid node type")
+					panic("invalid node type")
 				}
 			}
 		} else if path == n.path {
@@ -508,7 +512,7 @@
 				return append(ciPath, path...), true
 
 			default:
-				panic("Invalid node type")
+				panic("invalid node type")
 			}
 		} else {
 			// We should have reached the node containing the handle.
diff --git a/tree_test.go b/tree_test.go
index 262681b..64f26d1 100644
--- a/tree_test.go
+++ b/tree_test.go
@@ -358,7 +358,7 @@
 			tree.addRoute(route, nil)
 		})
 
-		if rs, ok := recv.(string); !ok || rs != panicMsg {
+		if rs, ok := recv.(string); !ok || !strings.HasPrefix(rs, panicMsg) {
 			t.Fatalf(`"Expected panic "%s" for route '%s', got "%v"`, panicMsg, route, recv)
 		}
 	}
@@ -584,6 +584,8 @@
 }
 
 func TestTreeInvalidNodeType(t *testing.T) {
+	const panicMsg = "invalid node type"
+
 	tree := &node{}
 	tree.addRoute("/", fakeHandler("/"))
 	tree.addRoute("/:page", fakeHandler("/:page"))
@@ -595,15 +597,15 @@
 	recv := catchPanic(func() {
 		tree.getValue("/test")
 	})
-	if rs, ok := recv.(string); !ok || rs != "Invalid node type" {
-		t.Fatalf(`Expected panic "Invalid node type", got "%v"`, recv)
+	if rs, ok := recv.(string); !ok || rs != panicMsg {
+		t.Fatalf("Expected panic '"+panicMsg+"', got '%v'", recv)
 	}
 
 	// case-insensitive lookup
 	recv = catchPanic(func() {
 		tree.findCaseInsensitivePath("/test", true)
 	})
-	if rs, ok := recv.(string); !ok || rs != "Invalid node type" {
-		t.Fatalf(`Expected panic "Invalid node type", got "%v"`, recv)
+	if rs, ok := recv.(string); !ok || rs != panicMsg {
+		t.Fatalf("Expected panic '"+panicMsg+"', got '%v'", recv)
 	}
 }