From fc3f4e675f8950048b4c1f0d98a7985111cb7c7c Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Wed, 16 May 2012 08:50:25 -0500 Subject: [PATCH] added a ``dissection'' of a contract error message to the Guide closes PR 12738 --- .../scribblings/guide/contracts-intro.scrbl | 16 +-------- .../guide/contracts-simple-function.scrbl | 35 ++++++++++++++++++- 2 files changed, 35 insertions(+), 16 deletions(-) diff --git a/collects/scribblings/guide/contracts-intro.scrbl b/collects/scribblings/guide/contracts-intro.scrbl index 663f223b27..2914091dba 100644 --- a/collects/scribblings/guide/contracts-intro.scrbl +++ b/collects/scribblings/guide/contracts-intro.scrbl @@ -181,20 +181,6 @@ the module boundary for a second time. } -@;{ - -@ctc-section[#:tag "obligations"]{Imposing Obligations on a Module's Clients} - -On occasion, a module may want to enter a contract with -another module only if the other module abides by certain -rules. In other words, the module isn't just promising some -services, it also demands the client to deliver -something. That situation may happen when a module exports -a function, an object, a class, or some other construct that enables -values to flow in both directions. - -} - @ctc-section{Experimenting with Contracts and Modules} All of the contracts and modules in this chapter (excluding those just @@ -203,7 +189,7 @@ describing modules. Since modules serve as the boundary between parties in a contract, examples involve multiple modules. To experiment with multiple modules within a single module or within -DrRacket's @tech{definitions area}, use the +DrRacket's @tech{definitions area}, use Racket's submodules. For example, try the example earlier in this section like this: diff --git a/collects/scribblings/guide/contracts-simple-function.scrbl b/collects/scribblings/guide/contracts-simple-function.scrbl index e32ac32b1b..d2ab6ecad9 100644 --- a/collects/scribblings/guide/contracts-simple-function.scrbl +++ b/collects/scribblings/guide/contracts-simple-function.scrbl @@ -1,5 +1,8 @@ #lang scribble/doc -@(require scribble/manual scribble/eval "guide-utils.rkt" "contracts-utils.rkt" +@(require scribble/manual scribble/eval + scribble/core racket/list + scribble/racket + "guide-utils.rkt" "contracts-utils.rkt" (for-label racket/contract)) @title[#:tag "contract-func"]{Simple Contracts on Functions} @@ -385,3 +388,33 @@ With this little change, the error message becomes quite readable: contract-eval (require 'improved-bank-server) (deposit -10)] + +@; not sure why, but if I define str directly to be the +@; expression below, then it gets evaluated before the +@; expressions above it. +@(define str "huh?") + +@(begin + (set! str + (with-handlers ((exn:fail? exn-message)) + (contract-eval '(deposit -10)))) + "") + +@ctc-section[#:tag "dissecting-contract-errors"]{Dissecting a contract error message} + +@(define (lines a b) + (define lines (regexp-split #rx"\n" str)) + (table (style #f '()) + (map (λ (x) (list (paragraph error-color x))) + (take (drop lines a) b)))) + +In general, each contract error message consists of six sections: +@itemize[@item{a name for the function or method associated with the contract + and either the phrase ``contract violation'' or ``violated it's contract'' + depending on whether the contract was violated by the server or the + client; e.g. in the previous example: @lines[0 1]} + @item{a description of the precise aspect of the contract that was violated, @lines[1 1]} + @item{the complete contract plus a path into it showing which aspect was violated, @lines[2 2]} + @item{the module where the contract was put (or, more generally, the boundary that the contract mediates), @lines[4 1]} + @item{who was blamed, @lines[5 1]} + @item{and the source location where the contract appears. @lines[6 1]}]