Error handling

This commit is contained in:
Aaron Fischer 2021-03-25 10:43:58 +01:00
parent 8f331b3ff1
commit 9a30dec1c0
6 changed files with 62 additions and 16 deletions

View File

@ -5,6 +5,7 @@ import (
"f00860/kartograph-map-editor/pkg/web" "f00860/kartograph-map-editor/pkg/web"
"flag" "flag"
"fmt" "fmt"
"log"
"time" "time"
) )
@ -29,7 +30,12 @@ func main() {
return return
} }
world := generator.New(size, wastelands, mountains, ruins, seed) world, err := generator.New(size, wastelands, mountains, ruins, seed)
if err != nil {
log.Fatal(err)
return
}
switch output { switch output {
case "svg": case "svg":

View File

@ -7,6 +7,17 @@ import (
"github.com/ajstarks/svgo" "github.com/ajstarks/svgo"
) )
func ErrorSVG(err error, width int, height int) string {
buf := bytes.NewBufferString("")
canvas := svg.New(buf)
canvas.Start(width, height)
canvas.Text(width/2, height/2, err.Error(), "text-anchor:middle;font-size:3px;font-family:Courier New;font-weight:light;")
canvas.End()
return buf.String()
}
func (w World) SVG() string { func (w World) SVG() string {
// DIN-A5 // DIN-A5
width := 148 * 3 width := 148 * 3

View File

@ -91,7 +91,7 @@ func (w World) JSON() string {
return string(output) return string(output)
} }
func New(size int, numWastelands int, numMountains int, numRuins int, seed string) World { func New(size int, numWastelands int, numMountains int, numRuins int, seed string) (World, error) {
InitSeed(seed) InitSeed(seed)
w := World{ w := World{
@ -102,7 +102,9 @@ func New(size int, numWastelands int, numMountains int, numRuins int, seed strin
Seed: seed, Seed: seed,
} }
// TODO: Return error wenn kein Platz mehr da ist if size < 3 || size > 25 {
return World{}, errors.New("Spielfeldgröße nicht im Bereich 3..25.")
}
// All empty for start // All empty for start
for i := 0; i < w.Size*w.Size; i++ { for i := 0; i < w.Size*w.Size; i++ {
@ -114,6 +116,10 @@ func New(size int, numWastelands int, numMountains int, numRuins int, seed strin
var wastelands []int var wastelands []int
if numWastelands > 0 { if numWastelands > 0 {
if numWastelands > size*size {
return World{}, errors.New("Zu viele Ödlandfelder.")
}
startPos := roll(w.Size-1) + roll(w.Size-1)*w.Size startPos := roll(w.Size-1) + roll(w.Size-1)*w.Size
w.place(WastelandTerritory, startPos) w.place(WastelandTerritory, startPos)
wastelands = append(wastelands, startPos) wastelands = append(wastelands, startPos)
@ -150,6 +156,10 @@ func New(size int, numWastelands int, numMountains int, numRuins int, seed strin
candidates = append(candidates, pos) candidates = append(candidates, pos)
} }
} }
if len(candidates) < 1 {
return World{}, errors.New("Zu viele Berge.")
}
w.place(MountainTerritory, randomItem(candidates)) w.place(MountainTerritory, randomItem(candidates))
} }
@ -165,10 +175,13 @@ func New(size int, numWastelands int, numMountains int, numRuins int, seed strin
candidates = append(candidates, pos) candidates = append(candidates, pos)
} }
} }
if len(candidates) < 1 {
return World{}, errors.New("Zu viele Ruinen.")
}
w.place(RuinsTerritory, randomItem(candidates)) w.place(RuinsTerritory, randomItem(candidates))
} }
return w return w, nil
} }
func InitSeed(seed string) { func InitSeed(seed string) {

View File

@ -3,6 +3,7 @@ package web
import ( import (
"embed" "embed"
"f00860/kartograph-map-editor/pkg/generator" "f00860/kartograph-map-editor/pkg/generator"
"fmt"
"html/template" "html/template"
"io" "io"
"log" "log"
@ -33,7 +34,7 @@ func Start(address string, port int) {
} }
} }
func worldFromRequest(req *http.Request) generator.World { func worldFromRequest(req *http.Request) (generator.World, error) {
size, err := strconv.Atoi(req.URL.Query().Get("s")) size, err := strconv.Atoi(req.URL.Query().Get("s"))
if err != nil { if err != nil {
size = 11 size = 11
@ -59,16 +60,30 @@ func worldFromRequest(req *http.Request) generator.World {
} }
func mapHandler(w http.ResponseWriter, req *http.Request) { func mapHandler(w http.ResponseWriter, req *http.Request) {
world := worldFromRequest(req)
log.Printf("GET /map.svg?%v (%v)", req.URL.Query().Encode(), req.RemoteAddr) log.Printf("GET /map.svg?%v (%v)", req.URL.Query().Encode(), req.RemoteAddr)
var SVGContent string
world, err := worldFromRequest(req)
if err != nil {
SVGContent = generator.ErrorSVG(err, 100, 100)
} else {
SVGContent = world.SVG()
}
w.Header().Set("Content-Type", "image/svg+xml") w.Header().Set("Content-Type", "image/svg+xml")
w.Header().Set("Content-Length", strconv.Itoa(len(world.SVG()))) w.Header().Set("Content-Length", strconv.Itoa(len(SVGContent)))
io.WriteString(w, world.SVG()) io.WriteString(w, SVGContent)
} }
func printHandler(w http.ResponseWriter, req *http.Request) { func printHandler(w http.ResponseWriter, req *http.Request) {
world := worldFromRequest(req)
log.Printf("GET /print?%v (%v)", req.URL.Query().Encode(), req.RemoteAddr) log.Printf("GET /print?%v (%v)", req.URL.Query().Encode(), req.RemoteAddr)
world, err := worldFromRequest(req)
if err != nil {
fmt.Print(err)
return
}
tpl, err := template.ParseFS(templateFiles, "templates/print.tpl.html") tpl, err := template.ParseFS(templateFiles, "templates/print.tpl.html")
if err != nil { if err != nil {
@ -80,7 +95,7 @@ func printHandler(w http.ResponseWriter, req *http.Request) {
func indexHandler(w http.ResponseWriter, req *http.Request) { func indexHandler(w http.ResponseWriter, req *http.Request) {
seed := generator.RandomSeed() seed := generator.RandomSeed()
world := generator.New(11, 7, 5, 6, seed) world, _ := generator.New(11, 7, 5, 6, seed)
log.Printf("GET / (%v) Seed: %v", req.RemoteAddr, seed) log.Printf("GET / (%v) Seed: %v", req.RemoteAddr, seed)
tpl, err := template.ParseFS(templateFiles, "templates/index.tpl.html") tpl, err := template.ParseFS(templateFiles, "templates/index.tpl.html")

View File

@ -7,19 +7,20 @@ document.addEventListener('DOMContentLoaded', function() {
let map = document.querySelector('.map') let map = document.querySelector('.map')
// Generate new random seed // Generate new random seed
let newMapUrl = '/map.svg?seed=' + seed + let newMapParams = '?seed=' + seed +
'&s=' + size + '&s=' + size +
'&w=' + wastelands + '&w=' + wastelands +
'&m=' + mountains + '&m=' + mountains +
'&r=' + ruins '&r=' + ruins
document.querySelector('.map').setAttribute('src', newMapUrl); document.querySelector('.map').setAttribute('src', '/map.svg' + newMapParams);
document.querySelector('#map-link').setAttribute('href', newMapUrl); document.querySelector('#print-button').setAttribute('data-target', '/print' + newMapParams);
document.querySelector('#map-button').setAttribute('data-target', '/map.svg' + newMapParams);
document.querySelector('#map-link').setAttribute('data-target', '/map.svg' + newMapParams);
}; };
let actionButtons = document.querySelectorAll('button[class="action"]'); let actionButtons = document.querySelectorAll('button[class="action"]');
Array.prototype.forEach.call(actionButtons, function(action, i) { Array.prototype.forEach.call(actionButtons, function(action, i) {
action.addEventListener('click', function(e) { action.addEventListener('click', function(e) {
console.log("adsf");
document.location.href = e.target.getAttribute('data-target'); document.location.href = e.target.getAttribute('data-target');
}); });
}); });

View File

@ -49,8 +49,8 @@
<input type="button" name="refresh" value="Neu generieren"> <input type="button" name="refresh" value="Neu generieren">
</form> </form>
<button class="action" data-target="/print?seed={{ .Seed }}&s={{ .Size }}&w={{ .Wastelands }}&r={{ .Ruins }}&m={{ .Mountains }}">Drucken</button> <button class="action" id="print-button" data-target="/print?seed={{ .Seed }}&s={{ .Size }}&w={{ .Wastelands }}&r={{ .Ruins }}&m={{ .Mountains }}">Drucken</button>
<button class="action" data-target="/map.svg?seed={{ .Seed }}&s={{ .Size }}&w={{ .Wastelands }}&r={{ .Ruins }}&m={{ .Mountains }}">Direktlink</button> <button class="action" id="map-button" data-target="/map.svg?seed={{ .Seed }}&s={{ .Size }}&w={{ .Wastelands }}&r={{ .Ruins }}&m={{ .Mountains }}">Direktlink</button>
<p>2011 <a href="https://aaron-fischer.net/">Aaron Fischer</a></p> <p>2011 <a href="https://aaron-fischer.net/">Aaron Fischer</a></p>
</body> </body>