GVKun编程网logo

Go1.13 之 Error Wrapping

7

想了解Go1.13之ErrorWrapping的新动态吗?本文将为您提供详细的信息,此外,我们还将为您介绍关于(转)SpringBoot:(hasnoexplicitmappingfor/error)

想了解Go1.13 之 Error Wrapping的新动态吗?本文将为您提供详细的信息,此外,我们还将为您介绍关于(转)SpringBoot :(has no explicit mapping for /error)、@Controller 文件相关 @RequestMapping @PostMapping @PutMapping @DeleteMapping @PatchMapping、com.intellij.openapi.editor.impl.softwrap.mapping.CachingSoftWrapDataMapper的实例源码、com.vaadin.ui.DragAndDropWrapper.WrapperTransferable的实例源码的新知识。

本文目录一览:

Go1.13 之 Error Wrapping

Go1.13 之 Error Wrapping


本文挑重点来看go1.13版本中对于错误处理部分提供的新功能(Error wrapping)(proposal参考资料1)。



提案中对于error新功能主要分两点:

  • error可以包裹着其他error。而不是以前的做法,以字符串拼接方式往上传递。

  • 使用%+v打印error时,带有堆栈信息,精确到函数名与行号。


  • 其实这两块功能,很早前Dave Cheney就在一篇博文中论述过他对error处理的理解,并给出相关的开源包github.com/pkg/errors(这个库现在也处于维护状态,不再接受新功能)。

    用过的同学应该比较熟悉,它解决的问题也是上面提到两点error新功能。



    功能1

    go1.13之前,方法内部逻辑中,遇到其它方法返回error时,一种粗暴的处理方式,直接return fmt.Errorf("operate failed %v", err)。这种做法问题是把err转换成为另一个字符串,原始的err被抹掉。

    如果想添加额外的错误信息,又不想抹掉原始的err,可以封装一个struct,上层通过err.Err.(type)的方式来检查,但显然加大编码复杂度。


    而用了go1.13之后,解决这个问题的方案就变成下面这样

    func foo() error { err := openSomething() // %v 变成了 %w return fmt.Errorf("operate failed %w", err)}
    func main() { err := foo() if errors.Is(err, *os.PathError) { var pe os.PathError errors.As(err, &pe) // dosomething } // 或者更直接 // var pe os.PathError // if errors.As(err, &pe) { // dosomething // }}

    这样原始的err不会变抹掉,通过errors.Is()方法可以检查出来。其次通过fmt.Println()输出是仍是字符串,样式与之前使用`%v`时相比较没有改变。


    还可以通过errors.As()方法将对应的原始err提取出来。


    所以用户在升级新版本后,有两个地方的代码需要转换下


    // beforeif err == io.ErrUnexpectedEOF// afterif errors.Is(err, io.ErrUnexpectedEOF)
    // beforeif e, ok := err.(*os.PathError); ok// aftervar e *os.PathErrorif errors.As(err, &e)

    用了这两种做法,即使API提供方后面更改返回的error含义,兼容成本较低。

    基于go1.13之前error不同的使用场景,官方写了FAQ,参考资料3。


    功能2

    打印error时带上堆栈信息功能很实用,之前遇到error时,排查都需要顺藤摸瓜的找到源头,比较浪费时间。


    坏消息,功能2在go1.13官方标准库中被腰斩了,推迟到go1.14。详细原因可参考资料2。



    好消息是官方提供了golang.org/x/xerrors。这个包完整实现了这两个新功能点,生产环境不易升级go版本的用户,可以尝鲜,或者是对已经升级为新版本的下游做兼容。


    看一下使用xerrors包打印error时带堆栈的效果。


    var myerror = xerrors.New("myerror")func foo() error { return myerror}func foo1() error { return xerrors.Errorf("foo1 : %w",foo())}func foo2() error { return xerrors.Errorf("foo2 : %w",foo1())}func main() { err := foo2() fmt.Printf("%v\n", err) fmt.Printf("%+v\n", err)}
    // 以下是输出foo2 : foo1 : myerrorfoo2 : main.foo2 /Users/cbsheng/goproject/src/test/main.go:116 - foo1 : main.foo1 /Users/cbsheng/goproject/src/test/main.go:113 - myerror: main.init /Users/cbsheng/goproject/src/test/main.go:108

    注意,xerrors.Errorf("foo1 : %w",foo())中必须以: %w的格式占位,否则不起作用。




    资料1:https://go.googlesource.com/proposal/+/master/design/29934-error-values.md

    资料2:https://github.com/golang/go/issues/29934#issuecomment-489682919

    资料3:https://github.com/golang/go/wiki/ErrorValueFAQ


    本文分享自微信公众号 - GoCN(golangchina)。
    如有侵权,请联系 support@oschina.cn 删除。
    本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

    (转)SpringBoot :(has no explicit mapping for /error)

    (转)SpringBoot :(has no explicit mapping for /error)

    转载自:https://www.cnblogs.com/panchanggui/p/9945261.html

    异常:This application has no explicit mapping for /error, so you are seeing this as a fallback.

     

    出现这个异常说明了跳转页面的url无对应的值.

    原因1:

    Application启动类的位置不对.要将Application类放在最外侧,即包含所有子包 
    原因:spring-boot会自动加载启动类所在包下及其子包下的所有组件.

    原因2:

    在springboot的配置文件:application.yml或application.properties中关于视图解析器的配置问题: 
    当pom文件下的spring-boot-starter-paren版本高时使用: 
    spring.mvc.view.prefix/spring.mvc.view.suffix 
    当pom文件下的spring-boot-starter-paren版本低时使用: 
    spring.view.prefix/spring.view.suffix

    原因3:

    控制器的URL路径书写问题 
    @RequestMapping(“xxxxxxxxxxxxxx”) 
    实际访问的路径与”xxx”不符合.

     

     

     

    启动类放的位置不对,启动类所在的package必需要包含Controller所在的package,当然直接把启动类放在项目最外层package中就最稳妥不过了。而后我们从头开始,重现问题及处理办法:

    都说SpringBoot简单,果然简单,这样就可以启动了:

    注意启动类所在包目录

    增加必要的依赖,连application.properties都不需要即可以启动了:

    最喜欢看见started

    然而在访问简单的controller接口的时候却出了错This application has no explicit mapping for /error, so you are seeing this as a fallback.:

    竟然找不到mapping

    大部分人都说这种情况通常是因为没有这个mapping对应的接口,然而我分明就是有,而且一定不可可以写错路径:

    这都可以找不到?

    后来终于有一个人猜对了起因:启动类放的位置不对,启动类所在的package必需要包含Controller所在的package。

    而后我改了下启动类StartWeeds.java的位置,果然正常了:

    注意启动类所在包目录

    重新启动并访问接口:

    问题处理!

    Thats All!

    @Controller 文件相关 @RequestMapping @PostMapping @PutMapping @DeleteMapping @PatchMapping

    @Controller 文件相关 @RequestMapping @PostMapping @PutMapping @DeleteMapping @PatchMapping

    https://blog.csdn.net/magi1201/article/details/82226289(copy)   

    最近学习看一些代码,发现对于发送请求这件事,有的地方用@RequestMapping,有的地方用@PostMapping,为了搞清楚区别,特意查了下spring 源代码,现在特此记录下。

     @GetMapping用于将HTTP get请求映射到特定处理程序的方法注解
    具体来说,@GetMapping是一个组合注解,是@RequestMapping(method = RequestMethod.GET)的缩写。

    @PostMapping用于将HTTP post请求映射到特定处理程序的方法注解
    具体来说,@PostMapping是一个组合注解,是@RequestMapping(method = RequestMethod.POST)的缩写。

    下面我们来看下@GetMapping的源码,可以对上面的两句释义给予充分的支撑。

    /**
     * Annotation for mapping HTTP {@code GET} requests onto specific handler
     * methods.
     *
     * <p>Specifically, {@code @GetMapping} is a <em>composed annotation</em> that
     * acts as a shortcut for {@code @RequestMapping(method = RequestMethod.GET)}.
     *
     *
     * @author Sam Brannen
     * @since 4.3
     * @see PostMapping
     * @see PutMapping
     * @see DeleteMapping
     * @see PatchMapping
     * @see RequestMapping
     */
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @RequestMapping(method = RequestMethod.GET)
    public @interface GetMapping {
     
        /**
         * Alias for {@link RequestMapping#name}.
         */
        @AliasFor(annotation = RequestMapping.class)
        String name() default "";
     
        ...
     
    }

    上面代码中,最关键的是 @RequestMapping(method = RequestMethod.GET),这行代码即说明@GetMapping就是@RequestMapping附加了请求方法。同时,可以看到@GetMapping这个注解 是spring4.3版本引入,同时引入的还有@PostMapping、@PutMapping、@DeleteMapping和@PatchMapping,一共5个注解。


    所以,一般情况下用@RequestMapping(method = RequestMethod. XXXX)即可。


    com.intellij.openapi.editor.impl.softwrap.mapping.CachingSoftWrapDataMapper的实例源码

    com.intellij.openapi.editor.impl.softwrap.mapping.CachingSoftWrapDataMapper的实例源码

    项目:intellij-ce-playground    文件:SoftWrapModelImpl.java   
    public SoftWrapModelImpl(@NotNull EditorImpl editor) {
      myEditor = editor;
      myStorage = new SoftWrapsstorage();
      myPainter = new CompositeSoftWrapPainter(editor);
      myEditorTextRepresentationHelper = new DefaultEditorTextRepresentationHelper(editor);
      myDataMapper = new CachingSoftWrapDataMapper(editor,myStorage);
      myApplianceManager = new SoftWrapApplianceManager(myStorage,editor,myPainter,myDataMapper);
      myVisualSizeManager = new SoftWrapAwareVisualSizeManager(myPainter);
    
      myApplianceManager.addListener(myVisualSizeManager);
      myApplianceManager.addListener(new SoftWrapAwareDocumentParsingListenerAdapter() {
        @Override
        public void recalculationEnds() {
          for (SoftWrapchangelistener listener : mySoftWrapListeners) {
            listener.recalculationEnds();
          }
        }
      });
      myUseSoftWraps = areSoftWrapsEnabledInEditor();
      myEditor.getColoRSScheme().getFontPreferences().copyTo(myFontPreferences);
    
      editor.addPropertychangelistener(this,this);
    
      myApplianceManager.addListener(myDataMapper);
    }
    
    项目:consulo    文件:SoftWrapModelImpl.java   
    public SoftWrapModelImpl(@Nonnull EditorImpl editor) {
      myEditor = editor;
      myStorage = new SoftWrapsstorage();
      myPainter = new CompositeSoftWrapPainter(editor);
      myEditorTextRepresentationHelper = new DefaultEditorTextRepresentationHelper(editor);
      myDataMapper = new CachingSoftWrapDataMapper(editor,myDataMapper);
    
      myApplianceManager.addListener(new SoftWrapAwareDocumentParsingListenerAdapter() {
        @Override
        public void recalculationEnds() {
          for (SoftWrapchangelistener listener : mySoftWrapListeners) {
            listener.recalculationEnds();
          }
        }
      });
      myUseSoftWraps = areSoftWrapsEnabledInEditor();
      myEditor.getColoRSScheme().getFontPreferences().copyTo(myFontPreferences);
    
      editor.addPropertychangelistener(this,this);
    
      myApplianceManager.addListener(myDataMapper);
      myEditor.getInlayModel().addListener(this,this);
    }
    
    项目:intellij-ce-playground    文件:SoftWrapModelImpl.java   
    @NotNull
    public CachingSoftWrapDataMapper getDataMapper() {
      return myDataMapper;
    }
    

    com.vaadin.ui.DragAndDropWrapper.WrapperTransferable的实例源码

    com.vaadin.ui.DragAndDropWrapper.WrapperTransferable的实例源码

    项目:hybridbpm    文件:ProcessModelLayout.java   
    @Override
    public void drop(DragAndDropEvent event) {
        WrapperTransferable transfrable = (WrapperTransferable) event.getTransferable();
        WrapperTargetDetails details = (WrapperTargetDetails) event.getTargetDetails();
        System.out.println("transfrable " + transfrable.getClass().getCanonicalName());
        System.out.println("transfrable.getDraggedComponent() " + transfrable.getDraggedComponent().getClass().getCanonicalName());
        if (transfrable.getDraggedComponent() instanceof Button) {
            // Calculate the drag coordinate difference
            int xChange = details.getMouseEvent().getClientX() - transfrable.getMouseDownEvent().getClientX();
            int yChange = details.getMouseEvent().getClientY() - transfrable.getMouseDownEvent().getClientY();
    
            // Move the component in the absolute layout
            AbsoluteLayout.ComponentPosition componentPosition = processModelLayout.getPosition(transfrable.getSourceComponent());
            componentPosition.setLeftValue(componentPosition.getLeftValue() + xChange);
            componentPosition.setTopValue(componentPosition.getTopValue() + yChange);
    
            ElementModelLayout elementModelLayout = (ElementModelLayout) ((Button) transfrable.getDraggedComponent()).getParent();
            TaskModel elementModel = elementModelLayout.getTaskModel();
            elementModel.setX(componentPosition.getLeftValue());
            elementModel.setY(componentPosition.getTopValue());
            processModel.getTaskModels().put(elementModel.getId(),elementModel);
            transitionManager.setValue(processModel.getTaskModels(),processModel.getTransitionModels());
            setTaskActive(elementModel);
        }
    }
    
    项目:hawkbit    文件:UploadLayout.java   
    @Override
    public void drop(final DragAndDropEvent event) {
        if (validate(event)) {
            final Html5File[] files = ((WrapperTransferable) event.getTransferable()).getFiles();
            // selected software module at the time of file drop is
            // considered for upload
    
            artifactUploadState.getSelectedBaseSwModuleId().ifPresent(selectedSwId -> {
                // reset the flag
                hasDirectory = false;
                final SoftwareModule softwareModule = softwareModuleManagement.get(selectedSwId)
                        .orElse(null);
                for (final Html5File file : files) {
                    processFile(file,softwareModule);
                }
                if (artifactUploadState.getNumberOfFileUploadsExpected().get() > 0) {
                    processBtn.setEnabled(false);
                } else {
                    // If the upload is not started,it signifies all
                    // dropped files as either duplicate or directory.so
                    // display message accordingly
                    displayCompositeMessage();
                }
            });
        }
    }
    
    项目:hawkbit    文件:UploadLayout.java   
    private boolean isFilesDropped(final DragAndDropEvent event) {
        if (event.getTransferable() instanceof WrapperTransferable) {
            final Html5File[] files = ((WrapperTransferable) event.getTransferable()).getFiles();
            return files != null;
        }
        return false;
    }
    

    关于Go1.13 之 Error Wrapping的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于(转)SpringBoot :(has no explicit mapping for /error)、@Controller 文件相关 @RequestMapping @PostMapping @PutMapping @DeleteMapping @PatchMapping、com.intellij.openapi.editor.impl.softwrap.mapping.CachingSoftWrapDataMapper的实例源码、com.vaadin.ui.DragAndDropWrapper.WrapperTransferable的实例源码等相关知识的信息别忘了在本站进行查找喔。

    本文标签:

    上一篇Bilibili 毛剑:Go 业务基础库之 Error(b站毛剑个人简历)

    下一篇ESH +OpenVINO(七)|预防损失检测的实时传感器融合用例