BeforeEach(func() {
			datastore.GetReturns(models.Container{}, errors.New("some-database-error"))
		})
		It("logs the error and returns with a 500", func() {
			handler, request := rataWrap(getHandler, "GET", "/containers/:container_id", rata.Params{"container_id": "some-container-id"})
			resp := httptest.NewRecorder()
			handler.ServeHTTP(resp, request)

			Expect(logger).To(gbytes.Say("get-container.*database-error"))
			Expect(resp.Code).To(Equal(http.StatusInternalServerError))
			Expect(resp.Body.String()).To(BeEmpty())
		})
	})

	Context("when the marshaling fails", func() {
		BeforeEach(func() {
			marshaler.MarshalReturns([]byte("some-junk"), errors.New("bang"))
		})

		It("logs the error and returns with a 500", func() {
			handler, request := rataWrap(getHandler, "GET", "/containers/:container_id", rata.Params{"container_id": "container-id-1"})
			resp := httptest.NewRecorder()
			handler.ServeHTTP(resp, request)

			Expect(logger).To(gbytes.Say("get-container.*marshal-failed.*bang"))
			Expect(resp.Code).To(Equal(http.StatusInternalServerError))
			Expect(resp.Body.String()).To(BeEmpty())
		})
	})
})
	})

	Context("when listing from the store fails", func() {
		It("should return a 500 error and log", func() {
			dataStore.AllReturns(nil, errors.New("teapot"))

			req, err := http.NewRequest("GET", "/containers", nil)
			Expect(err).NotTo(HaveOccurred())
			resp := httptest.NewRecorder()
			handler.ServeHTTP(resp, req)

			Expect(resp.Code).To(Equal(http.StatusInternalServerError))
			Expect(logger).To(gbytes.Say("list-containers.*datastore-all-failed.*teapot"))
		})
	})

	Context("when marshaling fails", func() {
		It("should return a 500 error", func() {
			marshaler.MarshalReturns(nil, errors.New("teapot"))

			req, err := http.NewRequest("GET", "/containers", nil)
			Expect(err).NotTo(HaveOccurred())
			resp := httptest.NewRecorder()
			handler.ServeHTTP(resp, req)

			Expect(resp.Code).To(Equal(http.StatusInternalServerError))
			Expect(logger).To(gbytes.Say("list-containers.*marshal-failed.*teapot"))
		})
	})
})
		Context("when there are errors", func() {
			Context("the URL cannot be built", func() {
				BeforeEach(func() {
					jsonClient.BaseURL = "::/not-#%#%#-a-valid-base-url"
				})

				It("returns a meaningful error", func() {
					err := jsonClient.BuildAndDo(config)
					Expect(err).To(MatchError("build url: parse ::/not-: missing protocol scheme"))
				})
			})

			Context("the request body cannot be marshalled", func() {
				BeforeEach(func() {
					marshaler.MarshalReturns(nil, errors.New("something went wrong"))
				})

				It("should return an error", func() {
					err := jsonClient.BuildAndDo(config)
					Expect(err).To(MatchError("failed to marshal request: something went wrong"))
				})
			})

			Context("reading the response body read fails", func() {
				BeforeEach(func() {
					mockHttpClient := &fakes.HTTPClient{}
					mockHttpClient.DoReturns(&http.Response{
						StatusCode: 201,
						Body:       &testsupport.BadReader{},
					}, nil)
		BeforeEach(func() {
			controller.AddReturns(nil, errors.New("tomato"))
		})

		It("should respond with code 500 and log the error", func() {
			resp := httptest.NewRecorder()
			handler.ServeHTTP(resp, request)

			Expect(logger).To(gbytes.Say("cni-add.controller-add.*tomato"))
			Expect(resp.Body.String()).To(MatchJSON(`{ "error": "tomato" }`))
			Expect(resp.Code).To(Equal(http.StatusInternalServerError))
		})

		Context("when writing the error response fails", func() {
			BeforeEach(func() {
				marshaler.MarshalReturns(nil, errors.New("potato"))
			})
			It("should log both errors", func() {
				resp := httptest.NewRecorder()
				handler.ServeHTTP(resp, request)

				Expect(logger).To(gbytes.Say("cni-add.controller-add.*tomato"))
				Expect(logger).To(gbytes.Say("cni-add.marshal-error.*potato"))
				Expect(resp.Code).To(Equal(http.StatusInternalServerError))
			})
		})
	})

	Context("when marshaling the result fails", func() {
		It("should return 500 and log the error", func() {
			marshaler.MarshalReturns([]byte(`bad`), errors.New("banana"))
	Context("when the controller returns an error", func() {
		BeforeEach(func() {
			controller.DelReturns(errors.New("tomato"))
		})

		It("should respond with code 500 and log the error", func() {
			resp := httptest.NewRecorder()
			handler.ServeHTTP(resp, request)

			Expect(logger).To(gbytes.Say("cni-del.controller-del.*tomato"))
			Expect(resp.Body.String()).To(MatchJSON(`{ "error": "tomato" }`))
			Expect(resp.Code).To(Equal(http.StatusInternalServerError))
		})

		Context("when writing the error response fails", func() {
			BeforeEach(func() {
				marshaler.MarshalReturns(nil, errors.New("potato"))
			})
			It("should log both errors", func() {
				resp := httptest.NewRecorder()
				handler.ServeHTTP(resp, request)

				Expect(logger).To(gbytes.Say("cni-del.controller-del.*tomato"))
				Expect(logger).To(gbytes.Say("cni-del.marshal-error.*potato"))
				Expect(resp.Code).To(Equal(http.StatusInternalServerError))
			})
		})
	})
})