Fix error handling in renderStatic #64
| @ -145,5 +145,17 @@ func TestIssue53(t *testing.T) { | ||||
| 		} | ||||
| 		return nil | ||||
| 	}) | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| func TestIssue60(t *testing.T) { | ||||
| 	srv, _ := createTemporaryRouter(t) | ||||
| 
 | ||||
| 	// Request a nonexistent static file | ||||
| 	req, err := http.NewRequest("GET", "/css/nonexistent_file.css", nil) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 	rr := httptest.NewRecorder() | ||||
| 	srv.ServeHTTP(rr, req) | ||||
| 	checkStatusCode(t, rr, http.StatusNotFound) | ||||
| } | ||||
|  | ||||
							
								
								
									
										16
									
								
								router.go
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								router.go
									
									
									
									
									
								
							| @ -33,6 +33,7 @@ func (rl *rushlink) recoveryMiddleware(next http.Handler) http.Handler { | ||||
| 		defer func() { | ||||
| 			defer func() { | ||||
| 				if err := recover(); err != nil { | ||||
| 					w.WriteHeader(500) | ||||
| 					log.Printf("error: panic while recovering from another panic: %v\n", err) | ||||
| 					debug.PrintStack() | ||||
| 					fmt.Fprintf(w, "internal server error: %v\n", err) | ||||
| @ -40,6 +41,7 @@ func (rl *rushlink) recoveryMiddleware(next http.Handler) http.Handler { | ||||
| 			}() | ||||
| 
 | ||||
| 			if err := recover(); err != nil { | ||||
| 				w.WriteHeader(500) | ||||
|  | ||||
| 				log.Printf("error: %v\n", err) | ||||
| 				debug.PrintStack() | ||||
| 				rl.renderInternalServerError(w, r, err) | ||||
| @ -80,10 +82,13 @@ func (w *statusResponseWriter) WriteHeader(statusCode int) { | ||||
| } | ||||
| 
 | ||||
| // CreateMainRouter creates the main Gorilla router for the application. | ||||
| // | ||||
| // This function will not populate the  router with an error-recovery and | ||||
| // metrics-reporting middleware. If these middleware are required, then the | ||||
| // caller should encapsulate this router inside of another router and register | ||||
| // the middlewares on the encapsulating router. | ||||
| func CreateMainRouter(rl *rushlink) *mux.Router { | ||||
| 	router := mux.NewRouter() | ||||
| 	router.Use(rl.recoveryMiddleware) | ||||
| 	router.Use(rl.metricsMiddleware) | ||||
| 	router.HandleFunc("/{path:img/"+staticFilenameExpr+"}", rl.staticGetHandler).Methods("GET", "HEAD") | ||||
| 	router.HandleFunc("/{path:css/"+staticFilenameExpr+"}", rl.staticGetHandler).Methods("GET", "HEAD") | ||||
| 	router.HandleFunc("/{path:js/"+staticFilenameExpr+"}", rl.staticGetHandler).Methods("GET", "HEAD") | ||||
| @ -118,8 +123,13 @@ func StartMainServer(addr string, db *db.Database, fs *db.FileStore, rawRootURL | ||||
| 		rootURL: rootURL, | ||||
| 	} | ||||
| 
 | ||||
| 	router := mux.NewRouter() | ||||
| 	router.Use(rl.metricsMiddleware) | ||||
| 	router.Use(rl.recoveryMiddleware) | ||||
| 	router.Handle("/", CreateMainRouter(&rl)) | ||||
| 
 | ||||
| 	srv := &http.Server{ | ||||
| 		Handler:      CreateMainRouter(&rl), | ||||
| 		Handler:      router, | ||||
| 		Addr:         addr, | ||||
| 		WriteTimeout: 15 * time.Second, | ||||
| 		ReadTimeout:  15 * time.Second, | ||||
|  | ||||
							
								
								
									
										8
									
								
								views.go
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								views.go
									
									
									
									
									
								
							| @ -88,7 +88,7 @@ func mapExtend(m map[string]interface{}, key string, value interface{}) { | ||||
| 
 | ||||
| func (rl *rushlink) renderStatic(w http.ResponseWriter, r *http.Request, path string) { | ||||
| 	var modTime time.Time | ||||
| 	if info, err := AssetInfo(path); err != nil { | ||||
| 	if info, err := AssetInfo(path); err == nil { | ||||
| 		modTime = info.ModTime() | ||||
| 	} | ||||
| 	contents, err := Asset(path) | ||||
| @ -118,7 +118,12 @@ func (rl *rushlink) render(w http.ResponseWriter, r *http.Request, status int, t | ||||
| 			err = fmt.Errorf("'%v' not in textTemplates", tmplName) | ||||
| 			break | ||||
| 		} | ||||
| 		if status != 0 { | ||||
| 			w.WriteHeader(status) | ||||
| 		} | ||||
| 		if r.Method != "HEAD" { | ||||
| 			err = tmpl.Execute(w, data) | ||||
| 		} | ||||
| 	case "text/html": | ||||
| 		w.Header().Set("Content-Type", "text/html") | ||||
| 		tmpl := htmlTemplates[tmplName] | ||||
| @ -142,7 +147,6 @@ func (rl *rushlink) render(w http.ResponseWriter, r *http.Request, status int, t | ||||
| 		if status != 0 { | ||||
| 			w.WriteHeader(status) | ||||
| 		} | ||||
| 
 | ||||
| 		if r.Method != "HEAD" { | ||||
| 			err = tmpl.Execute(w, data) | ||||
| 		} | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	
Can we definitively state that
panic()s are caused due to errors on the server side?Yes.
panics during runtime should always indicate a bug.